Django Academy · Урок

Поиск проблемы N+1

Распознавайте классическую ловушку запросов для каждой строки

Урок 1 из 413 шагов

«Поиск проблемы N+1» — бесплатный урок Django Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Django Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Django Academy содержит 4 уроков всего.

Что означает N+1

Проблема N+1 возникает, когда код выполняет один запрос для получения списка, а затем ещё по одному запросу для каждого элемента списка. 🐢

Где она скрывается

Обычно она скрывается в цикле по объектам, когда на каждой итерации снова и снова выполняется обращение к связанным данным в базе.

Небольшой пример

Представьте, что Вы выводите список книг и печатаете автора каждой. Приведённый ниже цикл выглядит безобидно, но запускает новый запрос на каждой строке.

for book in Book.objects.all():
    print(book.author.name)

Подсчёт запросов

Один запрос загружает все книги. Затем каждое обращение к book.author выполняет собственный запрос, поэтому для 100 книг получается 101 обращение к базе данных.

Почему 1, а затем N

Отсюда и название: 1 запрос для исходного списка плюс N дополнительных запросов — по одному для каждого затронутого связанного объекта.

Причина — ленивая загрузка

Django загружает связанные строки лениво, только при обращении к ним. Для одного объекта это удобно, но внутри цикла создаёт проблемы.

Плохая масштабируемость

Проблема растёт вместе с объёмом данных. Десять строк работают нормально, но десять тысяч превращают загрузку одной страницы в поток запросов.

Шаблоны тоже могут её вызвать

Шаблон, который выводит связанные данные внутри цикла for, создаёт точно такую же лавину запросов, даже если в Python Вы не видите цикла.

{% for book in books %}
  {{ book.author.name }}
{% endfor %}

Как её обнаружить

Ищите обращение к связанному объекту, например obj.parent, внутри цикла. Такой шаблон всегда является предупреждающим признаком.

Сделайте запросы видимыми

Во время DEBUG можно напрямую подсчитать запросы с помощью connection.queries и проверить, сколько обращений к базе данных действительно выполняет представление.

from django.db import connection
print(len(connection.queries))

Хорошая новость

Как только Вы увидите проблему, Django предложит два инструмента, которые объединят все эти запросы всего в несколько. Далее Вы познакомитесь с ними. 🚀

Быстрая проверка

Убедимся, что схема N+1 Вам понятна.

Повторение

Проблема N+1 — это один запрос для списка и по одному запросу для каждого связанного объекта, вызванные ленивой загрузкой внутри циклов. Ищите обращения к связанным данным в цикле. ✅

Можно начать бесплатно

Изучай Python с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
30
Уроки
120

Часто задаваемые вопросы

Урок «Поиск проблемы N+1» бесплатный?

Да — полный текст урока «Поиск проблемы N+1» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Django Academy, подпишись на CoddyKit PRO. Курс Django Academy содержит 4 уроков всего.

Чему я научусь в уроке «Поиск проблемы N+1»?

Распознавайте классическую ловушку запросов для каждой строки Ты практикуешь Django Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Django Academy?

Предыдущий опыт не требуется. Django Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «Поиск проблемы N+1»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Django Academy?

Да. Каждый урок Django Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Поиск проблемы N+1
  2. select_related для ForeignKey
  3. prefetch_related для M2M
  4. Профилирование с Debug Toolbar
← Назад к Django Academy