N+1 문제는 주로 지연 로딩( LAZY ) 환경에서 연관된 엔티티에 접근할 때 발생한다.
JPA는 엔티티를 조회할 때 연관된 엔티티를 즉시 조회하지 않고, 실제로 해당 엔티티에 접근하는 시점에 쿼리를 실행한다.
이로 인해 부모 엔티티가 N개라면, 각 부모의 연관 엔티티에 접근할 때마다 추가적인 SELECT 쿼리가 실행되어 N+1 문제가 발생한다.
하지만 N+1 문제의 본질적인 원인은 단순히 LAZY 설정 자체가 아니라 연관된 엔티티를 한 번에 조회하지 않고, 엔티티 단위로 개별 조회하는 조회 전략에 있다.
즉시 로딩( EAGER ) 전략을 사용하더라도 JPQL 조회 방식에 따라 유사한 N+1 문제가 발생할 수 있다.
@Query("SELECT p FROM Parent p JOIN FETCH p.children")
List<Parent> findAllWithChildren();-> 이렇게 Fetch Join을 통해 1번의 쿼리로 부모와 자식을 모두 가져올 수 있음@EntityGraph(attributePaths = "children")
List<Parent> findAll();spring:
jpa:
properties:
hibernate.default_batch_fetch_size: 100JPA를 사용할 때 가장 자주 마주치는 성능 이슈 중 하나인 N+1에 대해 알아보았다.
단순히 로딩 전략만으로 판단하기보다는, 조회 패턴과 쿼리 전략을 함께 고려해 상황에 맞는 해결 방법을 선택하도록 하자💯
깔끔한 글~~ 잘봤습니다!