Тысяча INSERT в логах и get_or_create под гонкой: как мы ускорили запись в Django

wignorbo 2 минуты назад Тысяча INSERT в логах и get_or_create под гонкой: как мы ускорили запись в Django Средний 17 мин 5 Python * Django * PostgreSQL * Туториал Вы когда-нибудь смотрели в логи и видели тысячу...
<5 — 2026'da uzaya kaç SpaceX Starship fırlatması ulaşacak?
Вот важная новость с фронта ИИ: wignorbo 2 минуты назад Тысяча INSERT в логах и get_or_create под гонкой: как мы ускорили запись в Django Средний 17 мин 5 Python * Django * PostgreSQL * Туториал Вы когда-нибудь смотрели в логи и видели тысячу одинаковых INSERT подряд? Или замечали, что под нагрузкой get_or_create начинает тормозить из‑за лишних round-trip и retry? В этой статье — про работу с большими объёмами данных в Django ORM.
От встроенных bulk_create / bulk_update до PostgreSQL COPY, реальных оптимизаций с прода и самописных атомарных аналогов get_or_create / update_or_create на одном UPSERT. Я ведущий разработчик в CodeScoring; ниже — то, что мы проходили на реальных сканах зависимостей, а не пересказ документации. Если вы уже знаете, что такое bulk_create, можно начать с подводных камней или с продовых примеров.
Технические детали
СодержаниеЗачем нужны bulk-операцииВстроенные bulk_create и bulk_updateПодводные камни bulkРабота с конфликтами: ignore_conflicts и update_conflictsdjango-bulk-load и PostgreSQL COPYБенчмаркиРазность множеств: синхронизация состояния без upsertПримеры с продаСамописные atomic_get_or_create / update_or_createКогда что использоватьЗаключениеЗачем нужны bulk-операцииПредставьте кассу в магазине. Вы купили 100 товаров. Кассир может:Пробить каждый товар отдельным чеком — 100 походов к терминалуПробить всё одним чекомВторой вариант быстрее не из-за магии, а потому что вы убрали накладные расходы: сетевой round-trip (туда-обратно до БД), разбор SQL, планирование запроса.
То же самое с ORM:for i in range(1000): Product. create(name=f' ', price=100 + i) Это тысяча отдельных INSERT. При latency 1 мс вы уже подарили секунду просто на сеть.
А ещё индексы, WAL, блокировки. В режиме autocommit каждый create() ещё и отдельная транзакция. Bulk-операции склеивают работу в один или несколько крупных SQL-запросов.
Отраслевые последствия
На импорте, миграциях данных, синхронизации справочников и аналитике это ускорение в разы, а иногда в десятки раз. Bulk особенно полезен, когда объектов много, а логика на один объект простая. Если на каждый объект нужна уникальная бизнес-логика с кучей ветвлений — сначала упростите модель данных, потом оптимизируйте запросы.
Встроенные bulk_create и bulk_updateСозданиеНаивный подход:for i in range(1000): Product. create( name=f' ', price=100 + i, ) INSERT INTO products (name, price) VALUES ('Product 0', 100); INSERT INTO products (name, price) VALUES ('Product 1', 101); -- ... ещё 998 раз Bulk:products = [ Product(name=f' ', price=100 + i) for i in range(1000) ] Product.
bulk_create(products) INSERT INTO products (name, price) VALUES ('Product 0', 100), ('Product 1', 101), -- ... ('Product 999', 1099); Один запрос вместо тысячи. ОбновлениеНаивно:for product in Product.
Этот прогресс даёт важные сигналы о будущем отрасли, и технологический мир внимательно наблюдает.





