간단한 쿼리를 작성해 개발하다
SQL Trace를 보고 이상한 점을 발견했습니다.
select
consumable0_.id as id1_10_,
...
...
...
from
consumable_po consumable0_ cross
join
supplier supplier1_ cross
...
...
where
...
...
...
갑자기 Cross join이 되었다는데...
아... 쿼리에서 뭔가 잘못되었다.. 라고 생각했고
바로 원인을 찾기 시작했습니다.
Cross Join은 아래와 같은 단점이 있습니다.
Cross Join은 집합의 모든 경우의 수를 구하기 때문에 일반 Join보다 성능 이슈가 발생합니다.
원인
원인은 바로 @Query JPQL을 사용하면서 Cross Join이 발생한 것입니다.
제가 작성한 쿼리에서는
JPQL에서 Join을 사용하지 않고
암묵적 Join (Where문에서 바로 연관관계 엔티티에 접근) 하면 발생하는 이슈입니다.
@Query("select t " +
"from Test t " +
"where t.animal.age = ?1 ")
JPQL의 내부 구현체인 Hibernate는 암묵적인 조인시 Cross Join을 사용하는 경향이 있기 때문에 발생한다고 합니다.
해결
해결 방안은 명시적 Join으로 변경하면 됩니다.
명시적 조인이란 Where에서 연관관계 엔티티에 접근하지 않고
명확하게 Join을 사용해 쿼리를 작성한다는 것입니다.
@Query("select t " +
"from Test t " +
"join t.animal a" +
"where a.age = ?1 ")
사내에서 발생한 이슈여서 자세한 쿼리는 블로그에 남길 수 없기 때문에
예제 코드로 블로그를 작성한 점은 양해부탁드리겠습니다.
참고
Querydsl (JPA) 에서 Cross Join 발생할 경우
JPA 기반의 환경에서 Querydsl를 사용하다보면 @OneToOne 관계에서 Join 쿼리 작성시 주의하지 않으면 Cross Join이 발생할 수 있습니다. CrossJoin 이란 집합에서 나올 수 있는 모든 경우를 이야기 합니다.
jojoldu.tistory.com