레이지 로딩 1+N 문제 해결

Stupefyee's avatar
Jan 10, 2025
레이지 로딩 1+N 문제 해결

1. 1+N 문제란?

  • 설명:
    • 메인 쿼리(1번 실행)로 데이터를 가져온 후, 각 연관된 데이터를 가져오기 위해 추가 쿼리(N번 실행)가 발생하는 문제.
    • 예: 부모 엔티티 1개에 대해 자식 엔티티 N개를 가져올 때, 총 1+N번의 쿼리 실행.
  • 원인:
    • 연관된 엔티티를 레이지 로딩(Lazy Loading)으로 설정했을 때 발생.

2. 해결 방법

  1. 페치 조인(Fetch Join) 사용
      • 연관 데이터를 한 번의 쿼리로 가져오기.
      • 예: SELECT p FROM Parent p JOIN FETCH p.children
  1. 배치 페치(Batch Fetching) 활용
      • spring.jpa.properties.hibernate.default_batch_fetch_size를 설정해, N개의 추가 쿼리를 **배치(batch)**로 처리.
      • 예: 한 번에 100개씩 조회하도록 설정.
  1. 엔티티 그래프(Entity Graph)
      • @EntityGraph를 사용해 필요한 연관 데이터를 즉시 로딩(Eager Loading)으로 명시.
      • 예: @EntityGraph(attributePaths = {"children"})
  1. 인쿼리(In Query) 사용 (추천)
      • 연관 데이터의 ID를 한 번에 조회한 뒤, 필요한 데이터를 가져오기.
      • 연관된 엔티티를 페치할 때 한 번에 가져올 엔티티 수를 설정하는 데 사용
      • properties에 아래의 설정을 추가. >> 설정한 정수의 수만큼 한번에 조회
        • spring.jpa.properties.hibernate.default_batch_fetch_size=100
      • 예:
        • SELECT * FROM Parent WHERE id IN (SELECT parent_id FROM Child WHERE condition);

3. 장점

  • 쿼리 효율성 증가: 불필요한 추가 쿼리를 줄임.
  • 성능 최적화: 데이터베이스와 애플리케이션 간 통신 비용 감소.
  • 확장성 개선: 대규모 데이터 처리에서 N+1 문제 완화.
 
Share article

stupefyee