Тысяча INSERT в логах и get_or_create под гонкой: как мы ускорили запись в Django
get_or_create() атомарный. select_for_update() защищает от гонок. UPSERT решает проблему конкурентной вставки. Звучит хорошо — пока не посмотреть на реальный SQL. Разбираю несколько неприятных мест Django + PostgreSQL, которые легко пропустить: retry после IntegrityError , гонки при синхронизации состояния, partial unique indexes с NULL и почему ON CONFLICT DO UPDATE может плодить dead tuples даже тогда, когда вы «ничего не меняете». Плюс реальный кейс: отказ от get_or_create() в цикле сократил время записи с 4.84 до 0.16 секунды . И да, в статье есть bulk/COPY. Но интереснее то, почему иногда bulk — вообще не тот инструмент . Читать далее
