공부/JPA

JPA N + 1 과 FetchJoin

kkkkkdddddhhhhh 2023. 12. 15. 20:18

JPA 강의를 보고 복습 겸 남겨보는 JPA N+1문제와 해결방법인 FetchJoin 

 

우선 첫번째 조회 API 방식은 fetchJoin을 사용하지않고 DTO로 변환 후 응답하는 방식

 

  

지연 로딩을 DTO Class에서 getter로 초기화하며 원하는 값들을 가져오기엔 성공했지만,

 

 

1개의 Order를 조회할때 쿼리가 한번

Lazy된 Member를 조회할때 또 쿼리가 한번

Lazy된 Delivery를 조회할때 또또 쿼리가 한번

 

여기서 두개의 Order를 조회한다면 DTO에서 지연로딩을 초기화 하는과정에서 또 Member와 Delivery 값을 가져오는 쿼리가 날라가 

Memeber, Delivery에 관한 쿼리가 총 4개가 날라간다. 

 

이는 성능 저하 이슈로 이어진다.

 

1개의 쿼리를 조회할때 + N 개의 쿼리가 추가로 더 날라가는 문제를 JPA N + 1 문제라한다.

 

해결 방법으로 

 

1. fetchJoin

2. Repository Query에서 DTO Class를 SELECT 해 원하는값만 심어주는 방식

 

2가지가 있다.

 

첫번째 fetch join 방식 

 

Order, Member, Delivery를 Join해 쿼리를 한개만 날린다.

fetch join을 사용하기전에는 각각의 테이블에 쿼리를 따로 하나하나씩 날렸지만 JOIN으로 테이블을 합쳐 받기때문

 

 

Member와 Delivery가 join되어 쿼리 딱 한개만 DB에 날라간다.

N+1문제를 해결했지만 연관된 테이블들을 합쳐 긴 테이블이 날라가므로 쿼리가 복잡해보이긴한다.

 

이런점을 보완해주는

 

두번째 SELECT 절에 DTO Class를 넣는 방식 

 

join을 사용하긴 하지만 fetch join을 사용하지않고 Select절에 DTO를 넣어 리턴값으로 바로 DTO를 받는다.

 

 

fetchJoin에 비해 쿼리가 줄어들었다.

 


 

두 해결 방식에는 장단점이 존재한다.

 

1. fetchJoin:

- 장점: Entity를 반환하므로 재사용성이 높다. 다른 DTO를 사용하는 API에도 재사용이 가능하다

- 단점: DTO를 바로 반환하는 방식에 비해 쿼리양이 많다. 

 

1. DTO return:

- 장점: 쿼리양이 fetchJoin 에 비해 적어 성능상 조금 더 우위에 있다.

- 단점: 반환하는 값이 DTO로 고정적이기때문에 재사용성이 낮다. 

 

강의에서는 fetchJoin 방식을 우선적으로 사용하되 정말 성능 저하 이슈가 해결이 안된다면 DTO를 바로 리턴하는 방식을 사용해보라고함.

 

 

Repository에는 Entity만을 반환해주는 순수성을 유지시켜주고,

 

DTO를 리턴하는 새로운 Repository를 생성해 사용하자.

'공부 > JPA' 카테고리의 다른 글

OSIV  (0) 2023.12.18
Collection fetch Join (~~ toMany 관계)  (0) 2023.12.16