간단이론정리/JPA

[JPA] N+1에 대하여

눕고싶은사람 2024. 7. 26. 20:19

1번의 쿼리를 날렸는데 조회된 데이터 갯수(N) 만큼 쿼리를 추가 실행하는 것.

 

일대다 혹은 다대일 관계를 조회 할 때 발생 할 수 있다. 하위 엔티티들을 첫 쿼리 실행시 한번에 가져오지 않고, Lazy Loading으로 필요한 곳에서 사용되어 쿼리가 실행될때 발생하는 문제.

 


해결방법

1. Fetch Join

N+1 자체가 발생하는 이유는 한쪽 테이블만 조회하고 연결된 다른 테이블은 따로 조회하기 때문이다.
미리 두 테이블을 JOIN 하여 한 번에 모든 데이터를 가져올 수 있다면 애초에 N+1 문제가 발생하지 않을 것이다.

 

단점

  • 쿼리 한번에 모든 데이터를 가져오기 때문에 JPA가 제공하는 Paging API 사용 불가능(Pageable 사용 불가)
  • 1:N 관계가 두 개 이상인 경우 사용 불가
  • 패치 조인 대상에게 별칭(as) 부여 불가능
  • 번거롭게 쿼리문을 작성해야

 

2. EntityGraph

attributePaths는 같이 조회할 연관 엔티티명을 적으면 된다. ,(콤마)를 통해 여러 개를 줄 수도 있다.
Fetch join과 동일하게 JPQL을 사용해 Query문을 작성하고 필요한 연관관계를 EntityGraph에 설정하면 된다.

 

Fetch join의 경우 inner join을 하는 반면에 EntityGraph는 outer join을 기본으로 한다.

(기본적으로 outer join 보다 inner join이 성능 최적화에 더 유리하다.)

 

3. Fetch Join & EntityGraph 사용 시 주의 점

카테시안 곱(Cartesian Product)이 발생하여 중복 데이터가 발생 할 수 있다.

(두 테이블 사이에 유효 join 조건을 적지 않았을 때 해당 테이블에 대한 모든 데이터를 전부 결합하여 테이블에 존재하는 행 갯수를 곱한만큼의 결과 값이 반환되는 것)

  • JPQL에 DISTINCT를 사용하여 중복 제거
  • 일대다 필드 타입을 Set으로 선언하여 중복 제거(LinkedHashSet을 사용하면 데이터 순서 보장 가능)

참고 및 출처

https://incheol-jung.gitbook.io/docs/q-and-a/spring/n+1#n1

 

N+1 문제 | Incheol's TECH BLOG

JPA N+1 문제에 대해 알아보자

incheol-jung.gitbook.io

https://jojoldu.tistory.com/165

 

JPA N+1 문제 및 해결방안

안녕하세요? 이번 시간엔 JPA의 N+1 문제에 대해 이야기 해보려고 합니다. 모든 코드는 Github에 있기 때문에 함께 보시면 더 이해하기 쉬우실 것 같습니다. (공부한 내용을 정리하는 Github와 세미나+

jojoldu.tistory.com

https://dev-coco.tistory.com/165#

 

[JPA] N+1 문제 원인 및 해결방법 알아보기

JPA를 사용하면 자주 만나게 되는 것이 N + 1 문제이다. N + 1 문제는 성능에 큰 영향을 줄 수 있기 때문에 N + 1 문제가 무엇이고 어떤 상황에 발생되는지, 어떻게 해결하면 되는지에 대해 알아보고

dev-coco.tistory.com

 

'간단이론정리 > JPA' 카테고리의 다른 글

[JPA] 영속성 컨텍스트 (Persistence Context)  (0) 2024.06.17