JPA의 N+1문제는 연관관계가 설정된 엔티티를 조회할 경우, 조회된 데이터 개수(N)만큼 연관관계의 조회 쿼리가 추가로 발생하는 현상입니다.
ex) 유저 한명이 쓴 게시글들을 조회할 때, 유저-게시글을 join한 형태의 쿼리문을 원했지만, N개의 게시글을 또 조회하는 쿼리가 날아가는 경우라고 생각하면 될 것 같습니다.
N+1 문제를 어떻게 해결할 수 있을까요?
N+1문제를 해결하기 위해서는 fetch join 또는 @EntityGraph를 사용해 볼 수 있습니다.
- fetch join
- 연관관계에 있는 엔티티를 한번에 즉시 로딩하는 구문입니다.
- 쿼리 한번에 모든 데이터를 가져오기 때문에 JPA가 제공하는 Paging API 사용 불가능 (Pageable 사용 불가)
- 1:N 관계가 두 개 이상인 경우 사용 불가
- fetch join 대상에게 별칭 (as) 부여 불가
- @EntityGraph
- fetch join과 비슷한 효과를 만들어내며, 쿼리 메서드에 해당 어노테이션을 추가해 사용할 수 있습니다.
- fetch join은 inner join을 하는 반면, @EntityGraph는 outer join을 기본으로 한다.
+) fetch join과 @EntityGraph 사용 시 주의점
fetch join과 @EntityGraph는 공통적으로 카테시안 곱(Cartesian Product) 발생하여 중복이 생길 수 있다.
중복 발생 문제 해결방법
- JPQL에 DISTINCT를 추가하여 중복 제거
- OneToMany 필드 타입을 Set으로 선언하여 중복 제거
해결 방법에 대해서 참고 블로그를 같이 보시는 걸 추천드립니다.(특히 fetch join)
혹여나 잘못된 내용이 있다면 댓글 부탁드리겠습니다 :)
참고
기술 면접 구독 서비스 - 매일메일 https://www.maeil-mail.kr/
https://programmer93.tistory.com/83
https://velog.io/@xogml951/JPA-N1-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EA%B2%B0-%EC%B4%9D%EC%A0%95%EB%A6%AC
https://dev-coco.tistory.com/165
'자잘한 cs' 카테고리의 다른 글
엔티티 매니저에 대해 설명해주세요. (0) | 2024.11.20 |
---|---|
JPA의 ddl-auto 옵션은 각각 어떤 동작을 하고 어떤 상황에서 사용해야 할까요? (0) | 2024.11.18 |
Redis가 빠른 이유 (0) | 2024.06.10 |
프록시 패턴이란? (0) | 2024.05.22 |
reverse proxy란? (0) | 2024.05.10 |