Mediumn-plus-1hibernate

Что такое N+1 проблема в ORM?

1Постановка

Разберём, что от вас хотят в этом вопросе и как к нему подступиться на собеседовании.

2Решение

N+1 — вместо одного запроса с JOIN делается 1 (родительский список) + N (по одному для каждого связанного).

// ПЛОХО: N+1 запросов
List<Order> orders = orderRepo.findAll();   // 1 SELECT
for (Order o : orders) {
    System.out.println(o.getUser().getName()); // N SELECTs!
}

// ХОРОШО: 1 запрос с JOIN FETCH
@Query("SELECT o FROM Order o JOIN FETCH o.user")
List<Order> findAllWithUsers();

// ИЛИ @EntityGraph
@EntityGraph(attributePaths = "user")
List<Order> findAll();

Другие решения: @BatchSize(size=50) (батчами по 50), @Fetch(FetchMode.SUBSELECT) (один SELECT IN (...)), DTO projection.

Detection: Hibernate logging (show_sql), p6spy, datasource-proxy. Для 1000 orders N+1 = 1001 запрос вместо 1.

3Как отвечать

  • Сначала уточните условия и ограничения, покажите аналитическое мышление.
  • Рассуждайте вслух — интервьюеру важен ход мысли, а не только финальный ответ.
  • Оцените сложность по времени и памяти (Big-O), если это алгоритмический вопрос.
💡

На реальном собеседовании Alffert подскажет развёрнутый ответ в реальном времени.