N+1 проблема
N+1 — один запрос превращается в серию дополнительных
Проблема N+1 возникает, когда приложение сначала получает список из N объектов одним запросом, а затем для каждого объекта отдельно загружает связанные данные. В результате вместо одного-двух осознанных запросов база получает 1 + N обращений.
List<Order> orders = entityManager.createQuery(
"select o from Order o",
Order.class)
.getResultList();
for (Order order : orders) {
System.out.println(order.getUser().getName());
}
Если связь user подгружается отдельно для каждого заказа,
цикл может незаметно создать множество SQL-запросов. На небольших тестовых данных код выглядит нормально,
а под реальной нагрузкой задержка резко растёт.
Лечить нужно конкретный сценарий загрузки
List<Order> orders = entityManager.createQuery(
"select o from Order o join fetch o.user",
Order.class)
.getResultList();
join fetch явно просит получить нужную связь вместе с основной выборкой.
Это один из способов устранить N+1 для конкретного запроса; в других случаях могут подойти entity graph,
batch fetching или другая форма выборки.
Не лечи N+1 глобальным EAGER.
Постоянная загрузка всех связей может заменить одну проблему другой. Сначала выясни, какие данные нужны конкретному use case и какие SQL-запросы реально выполняются.
Проверь себя
Разбор задания
Ментор знает решение и поможет тебе прийти к нему самостоятельно
Войди, чтобы использовать Ментора
Ментор учитывает текущую задачу и историю диалога.
Войти
Проверь важные нюансы и ответ после собственной попытки.
Войди, чтобы посмотреть решение
Решение и разбор доступны после авторизации.
Войти