Этот вопрос проверяет понимание типичной ORM-проблемы, которая приводит к резкому росту количества запросов к базе данных.
Проблема N+1 возникает, когда сначала выполняется один запрос для получения списка объектов, а затем по одному запросу для каждого объекта из этого списка. В итоге вместо 2 запросов выполняется N+1, где N — количество записей. Это часто происходит из-за ленивой загрузки связей в ORM. Такая схема резко увеличивает нагрузку на БД и замедляет приложение.
N+1 — одна из самых частых причин неожиданной деградации производительности при использовании ORM.
N+1 problem — ситуация, когда получение связанных данных приводит к выполнению одного основного запроса и дополнительных запросов для каждого элемента результата.
Рассмотрим пример:
Есть User и Order.
У пользователя может быть много заказов.
Связь User.orders загружается лениво.
users = session.execute(select(User)).scalars().all()
for user in users:
print(len(user.orders)) # отдельный запрос для каждого user
Что происходит:
1 запрос для списка пользователей.
N запросов для заказов каждого пользователя.
ORM по умолчанию:
не знает, нужны ли тебе связанные данные;
откладывает загрузку до момента обращения.
Это удобно для простых сценариев, но опасно в циклах.
Основные проблемы:
резкий рост количества запросов;
нагрузка на соединения БД;
рост времени ответа;
плохая масштабируемость.
Типичные признаки:
много одинаковых запросов в логах;
небольшие запросы, выполняемые сотни раз;
высокая нагрузка на БД при небольшом объеме данных.
N+1 — это не баг ORM, а следствие ленивой загрузки связей. Если не контролировать загрузку данных, приложение может начать выполнять сотни лишних запросов.