[내배캠 Spring TIL] N+1 문제
Spring
2024년 8월 22일
개발하면서 겪은 지연 로딩 관련 이슈를 정리해보려 한다.
지연 로딩 (Lazy Loading) #
지연 로딩은 JPA에서 엔티티의 연관된 데이터를 실제로 필요할 때까지 로딩하지 않고, 참조만 유지하다가 해당 데이터에 접근할 때 실제 쿼리를 실행하여 데이터를 로딩하는 기법이다.
이는 데이터베이스와의 불필요한 통신을 줄여 성능을 최적화하려는 목적을 가지고 있습니다.
예를 들어, A 엔티티가 B 엔티티와 1:N 관계를 가지고 있다고 가정하자. 이때 A 엔티티를 조회할 때 B 엔티티의 데이터를 즉시 로딩하지 않고, 필요할 때 B 데이터를 로딩하는 것이 지연 로딩이다.
N+1 문제 #
N+1 문제는 지연 로딩을 사용하는 경우 자주 발생하는 성능 문제로, 아래와 같은 상황에서 발생한다.
- A 엔티티를 조회하기 위해 하나의 쿼리(1)를 실행.
- 조회된 A 엔티티 리스트의 각각의 B 엔티티를 지연 로딩 방식으로 접근할 때마다 추가 쿼리(N)를 실행.
예를 들어, A 엔티티 10개를 조회하는 쿼리가 실행된다고 가정하자. 이때 각 A 엔티티에 연결된 B 엔티티들을 지연 로딩으로 접근하면, 추가로 10개의 쿼리가 발생하게 된다. 결국 총 11개의 쿼리가 실행된다. 이처럼 N개의 엔티티를 조회할 때, 1개의 메인 쿼리 + N개의 서브 쿼리가 실행되는 문제를 N+1 문제라고 한다.
N+1 문제의 해결 방법 #
패치 조인 (Fetch Join) #
JPQL에서 패치 조인을 사용하여 연관된 엔티티를 한 번의 쿼리로 함께 가져오는 방법. 연관관계로 걸려있는 엔티티를 한꺼번에 가져올 수 있다.
엔티티 그래프 (@EntityGraph) #
특정 엔티티를 조회할 때 함께 로딩할 연관된 엔티티를 지정하는 방법. JPQL 대신 사용할 수 있다.