Ответ
Основная цель оптимизации — сокращение количества запросов к базе данных (решение проблемы "N+1") и уменьшение объема передаваемых данных.
-
*`select_related(fields)
** Оптимизирует запросы к связанным объектам черезForeignKeyилиOneToOne. Он "подтягивает" связанные данные однимSQL JOIN` запросом, предотвращая дополнительные запросы в цикле.# Плохо: N+1 запросов (1 для постов + N для авторов) for post in Post.objects.all(): print(post.author.name) # Хорошо: 1 запрос с JOIN for post in Post.objects.select_related('author').all(): print(post.author.name) -
*`prefetch_related(lookups)
** Используется дляManyToManyFieldи обратныхForeignKey. В отличие отselect_related, он делает отдельный запрос для связанных объектов и "склеивает" данные в Python. Это эффективнее, чемJOIN` для связей "многие-ко-многим".# 1 запрос для постов + 1 запрос для всех тегов posts = Post.objects.prefetch_related('tags').all() -
only(*fields)иdefer(*fields)Позволяют загружать только указанные поля модели (only) или все, кроме указанных (defer). Это сокращает объем передаваемых данных и потребление памяти.# Загрузить только заголовки titles = Post.objects.only('title') -
values()иvalues_list()Возвращают словари или кортежи вместо полноценных объектов моделей. Это значительно быстрее, если вам нужны только данные и не требуются методы модели. -
annotate()иaggregate()Переносят вычисления (например,COUNT,SUM,AVG) на сторону базы данных, что намного эффективнее, чем делать это в Python.from django.db.models import Count # Получить авторов с количеством их постов authors = Author.objects.annotate(post_count=Count('posts')) -
exists()иcount()Для проверки наличия записи используйтеexists(), а для подсчета —count(). Они выполняют более легковесные SQL-запросы, чем загрузка всего QuerySet. -
bulk_create()иbulk_update()Для массового создания или обновления объектов используйте эти методы, чтобы выполнить операцию одним запросом вместо множества.
Рекомендация: Всегда анализируйте запросы с помощью django-debug-toolbar или connection.queries для выявления узких мест.