우리는 SQL을 알기 때문에 JOIN
이라는 쿼리를 알고 있다. 근데 JPA를 배우다 보면 N+1 문제를 직면하게 되고, 이를 해결하기 위한 방법으로 JOIN FETCH
라는 JPQL을 알게 됩니다.
근데 단순 JOIN과 JOIN FETCH는 동일한 쿼리를 DB에 쏜다는 것을 알고 계셨나요?
저는 깜짝 놀랐는데, 동일한 쿼리를 보냄에도 불구하고 이는 JPA를 다루는 차원에서 차이가 존재했습니다.
Join fetch
와 달리 실제 쿼리에서 select하는 entity만 영속화되고, 이를 조회하기 위해 join된 엔티티들에 대하여는 Join 쿼리를 날려서 검색 조건으로서는 활용되지만 이 객체들이 영속화되진 않습니다.
이는 우리가 익히 알듯이, select의 대상인 entity 외에도 연관관계의 entity들 모두 영속화시킵니다. 이는 일반적으로 fetchType을 LAZY로 설정하기 때문에 발생하는 N+1문제를 해결하고 성능을 최적화하기 위해 사용하게 됩니다.
위와 같은 차이를 바탕으로 다음과 같이 정리해볼 수 있습니다.
무작정 JOIN FETCH를 사용해서 전부 영속성 컨텍스트에 올리기보다, 만약 select의 대상이 되는 entity의 데이터만 필요한데 다른 연관관계 엔티티들의 값을 이용하여 필터링 정도만 필요한 거라면 JOIN
만 사용,
그렇지 않고 해당 엔티티의 데이터 뿐만 아니라 다른 연관관계 엔티티의 데이터도 필요한 경우 JOIN FETCH
사용! (N+!문제 떄문에)
따라서 단건 필터링 조회의 경우
JOIN
, 그렇지 않고 많은 조회를 하거나 전체 조회를 해야 하는 경우JOIN FETCH
를 사용하는 것이 좋을 것이다.