Выбор ответа Senior Django ORM и N+1 обновлено

Обработка миллиона строк

Вопрос

Management-команда обходит 5 млн записей for row in Event.objects.all(): и падает по памяти. Что поможет?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: .iterator(chunksize=2000): порции без кеширования QuerySet. Обычный обход QuerySet загружает и кеширует все объекты в памяти. iterator() отключает кеш результата и на PostgreSQL использует серверный курсор, отдавая строки порциями.

Варианты ответа

  1. .all().all(), чтобы сбросить кеш предыдущего QuerySet
  2. list(Event.objects.all()), чтобы загрузить всё одним запросом
  3. .order_by("?"), чтобы база отдавала строки без сортировки в памяти
  4. .iterator(chunk_size=2000): порции без кеширования QuerySetправильный ответ

Разбор

Обычный обход QuerySet загружает и кеширует все объекты в памяти. iterator() отключает кеш результата и на PostgreSQL использует серверный курсор, отдавая строки порциями. Для массовых изменений ещё лучше update() или пакетная обработка по диапазонам id. list() усугубит проблему, а order_by("?") это медленная случайная сортировка.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.