카테고리 없음

JPA 쿼리 분석

건우정 2024. 11. 24. 22:18

 

 

수행시간을 측정해보자.

 


1. EAGER 일 때 + findBy 메소드 그대로 활용

 

 

 

쿼리는 조인 없이 

 

 

 

총 3개의 쿼리가 수행되고,

수행 시간: 34ms

 

2. 1번의 케이스에서 fetchType이 LAZY로 바꾼다면

 

쿼리는 변하지 않는다.

쿼리가 수행되는 시점만 바뀐다.

수행 시간: 35ms

3. UserEntity 참조 없이, CouponEntity만 바로 가져오게 변경

 

 

쿼리는 1번만 수행되고 usercoupon이랑 coupon이랑 조인된다.

 

수행 시간: 12ms

 

 

분석 결과 : 

 

기존의 UserCouponEntity에서 findBy메소드로 자식 엔테디 CouponEntity, UserEntity를

자동으로 가져오는 LAZY EAGER 방식은 모두 JOIN 연산 없이 쿼리가 3번 일어나고,

 

UserCouponEntity에서 UserCouponEntity만 가져오는

@Query 개선된 쿼리는 JOIN(UserCouponEntity 조인 CouponEntity)을 통해서 1번의 쿼리만 수행된다.

 

테이블의 데이터 개수가 적으므로 조인의 영향은 거의 없고,

 

쿼리 수행 횟수만큼 시간이 늘어나는 것을 확인할 수 있다.

 

따라서 개선된 방식은 시행시간은 약 3배 줄었다.

 

테이블에 데이터 개수가 늘어나면 JOIN 비용이 급격하게 증가하므로, 

 

데이터 개수가 많을 때, 결과가 달라질 수 있다.

 

아니면 조인을 안하면서, UserEntity에 대한 쿼리는 수행되지 않도록 더 나은 방법이 있는지 생각해보자.

 

 


 

1번과 2번에서 ManyToOne JoinColmn에서 조인이 수행되지 않고 

쿼리의 개수만 늘어나는 것을 알 수 있다.

 

따라서, LAZY로 그대로 두고 Controller에서 Return할 때,
UserEntity는 참조하지 않으면서 CouponDTO의 목록만 뽑으면 될 것이다.

 

 

이렇게 하면 JOIN 없이 2번의 쿼리로 단축된다.

 

데이터가 많으면 JOIN을 안하고 2번의 쿼리가 더 나을 수도 있다.

 

수행 시간: 23ms

 

결론은

 

  EAGER LAZY @Query LAZY+UserEntity 참조 X  
조인 유무 X X O X  
수행시간 34ms 35ms 12ms 23ms  
쿼리 개수 3 3 1 2  
데이터 양이 많아지면 ? ? ? ?