N+1 문제는 연관관계가 있는 엔티티를 조회할 때, 부모 목록을 조회하는 쿼리 1번과 각 부모의 연관 데이터를 조회하는 쿼리 N번이 추가로 실행되는 문제입니다. 예를 들어 팀 10개를 한 번에 조회한 뒤 각 팀의 회원에 접근하면, 회원 조회 쿼리가 팀마다 실행되어 총 11번의 쿼리가 발생할 수 있습니다.

지연 로딩에서는 반복문 안에서 연관 엔티티에 처음 접근할 때 주로 발생합니다. 즉시 로딩도 JPQL이 연관관계를 항상 조인해서 가져오는 것은 아니므로, 조회 이후 연관 엔티티를 채우기 위한 추가 쿼리가 실행되어 N+1 문제가 발생할 수 있습니다.

대표적인 해결 방법은 다음과 같습니다.

  • Fetch Join: 필요한 연관 데이터를 한 쿼리로 함께 조회합니다.
  • EntityGraph: Repository 쿼리를 유지하면서 함께 조회할 연관관계를 지정합니다.
  • Batch Fetching: default_batch_fetch_size나 @BatchSize를 사용하여 여러 연관 엔티티를 IN 쿼리로 묶어 조회합니다.
  • DTO 조회: 화면이나 API에 필요한 필드만 조인하여 직접 조회합니다.

모든 연관관계를 항상 함께 조회하면 데이터 중복과 메모리 사용량이 늘 수 있으므로, 기본은 지연 로딩으로 두고 조회 용도에 맞는 방법을 선택하는 것이 좋습니다.

fetch join vs batch fetching
https://domean.tistory.com/323