기술면접 준비

N+1 문제의 발생 이유와 해결 방법에 대해 설명해주실 수 있을까요? 해결 방법은 3가지 이상

Albosa2lol 2024. 8. 20. 19:29

N+1 문제는 ORM(Object-Relational Mapping) 프레임워크에서 자주 발생하는 성능 문제 중 하나로, 주로 여러 개의 연관된 엔터티를 로드할 때 발생합니다.

발생 이유:

  • 예를 들어, 하나의 엔티티(예: Order)를 조회할 때, 이 엔티티와 연관된 다른 엔티티(예: OrderItem)를 조회하기 위해 추가적인 쿼리가 발생합니다.
  • 만약 Order 1개에 대해 OrderItem을 N개 가져와야 하는 상황이라면, 첫 번째 Order를 가져오는 1번의 쿼리 외에 각 OrderItem을 가져오기 위한 N번의 쿼리가 추가로 발생하게 됩니다.
  • 즉, 총 N+1번의 쿼리가 실행되므로 데이터베이스 부하가 증가하고 성능이 저하됩니다.

 

해결 방법:

즉시 로딩 (Eager Fetching) 또는 지연 로딩 (Lazy Fetching):

  • 즉시 로딩은 연관된 엔티티를 한 번에 조회하도록 ORM 설정을 변경하여 N+1 문제를 해결할 수 있습니다.
  • 지연 로딩을 사용하면 필요할 때만 데이터를 로드하게 되지만, 연관 데이터를 한꺼번에 가져오는 것이 필요하다면 적절한 Fetch 전략을 설정해야 합니다.

페치 조인(Fetch Join):

  • JPQL 또는 HQL에서 JOIN FETCH 구문을 사용하여 연관된 엔티티를 한 번에 조회합니다.
  • 이렇게 하면 한 번의 쿼리로 모든 관련 데이터를 가져올 수 있어 N+1 문제를 방지할 수 있습니다.

배치 크기 설정:

  • Hibernate의 @BatchSize 어노테이션이나 설정 파일을 통해 배치 크기를 조정하여, 한 번에 로드하는 연관 엔티티의 수를 늘려 다중 쿼리 실행을 최소화할 수 있습니다.
  • 이렇게 하면 N개의 개별 쿼리가 아닌, 몇 번의 쿼리로 데이터를 가져올 수 있습니다.

 

엔티티 그래프(Entity Graph):

  • JPA 2.1에서 도입된 기능으로, 특정 엔티티에 대한 쿼리를 수행할 때 로드할 연관 엔티티를 명시적으로 지정할 수 있습니다.
  • 동적 쿼리에서는 특히 유용하게 사용할 수 있습니다.