Выбор ответа Junior Django ORM и N+1 спрашивают часто обновлено
select_related против prefetch_related
Вопрос
Чем select_related отличается от prefetch_related?
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Правильный ответ: selectrelated делает JOIN «к одному», prefetchrelated отдельный запрос. Для ForeignKey и OneToOne достаточно JOIN, и данные приходят одним запросом.
Варианты ответа
- Это синонимы: оба делают JOIN, разница только в названии метода
select_relatedдля ManyToMany, аprefetch_relatedдля ForeignKeyprefetch_relatedкеширует результаты между HTTP-запросами пользователяselect_relatedделает JOIN «к одному»,prefetch_relatedотдельный запросправильный ответ
Разбор
Для ForeignKey и OneToOne достаточно JOIN, и данные приходят одним запросом. Для обратных FK и ManyToMany JOIN размножил бы строки, поэтому prefetch_related выполняет второй запрос WHERE ... IN (...) и раскладывает результаты по объектам. Между HTTP-запросами prefetch_related ничего не кеширует.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Ещё по теме «Django ORM и N+1»
- Задвоение сумм при нескольких annotate
- Посчитать SQL-запросы при ленивой загрузке
- Как prefetch_related склеивает данные
- exists() и count() вместо загрузки строк
- Атомарное увеличение счётчика
- Prefetch с вложенным select_related
- transaction.atomic
- Когда выполняется QuerySet