JPA

[JPA] Fetch Join 이란? N+1 이란? fetch join을 사용하는 이유

Jeong Jeon
반응형

JPA를 사용하면서 엄청 중요하다고 하는 fetch join에 대해서 간략하게 정리해 두려고한다.

모르고 남발하는 코드를 지양하자.

 

Fetch Join이란?

Fetch Join은 JPQL의 중요한 기능이다.                                                                          
성능최적화를 위해 사용하는데, LazyLoading으로 설정되어있는 아이들을 Eager로딩으로 땡겨올수있는 쿼리를 만든다. 


즉 연관된 엔티티나 컬렉션을 SQL 한번에 조회하는 기능이라고 보면될것같다.

=> 쿼리가 2번 날아갈 상황을 쿼리 1번으로 조회할 수 있게 해준다. SQL에는 없는 문법 
=> 지연로딩으로 설정했어도 fetch join을 사용하면 eager과 같이 동시에 조회하게 된다. (프록시가 아닌 실제 Entity이다)

 


예제로 회원과 팀을 함께 조회하고 싶은 상황에 맞추어 확인해보자.
SQL에서는 Join문을 통해 두 테이블을 한번에 조회한다. 이를 SQL과 Fetch join을 사용한 JPQL로 비교해보자.


1). JPQL with fetch join

select m from Member join fetch m.team


                                                                                                     
2). SQL

SELECT
M.*, T.*
FROM MEMBER M
INNER JOIN TEAM T ON M.TEAM_ID = T.TEAM_ID


간략한 설명으로 fetch join을 사용하는 이유를 설명하자면,
예를들어 팀과 멤버가 다대일 관계라고 생각해봤을때
N명의 멤버를 가져오기 위한 쿼리를 짜보면 JPQL을 사용했을때 N명의 멤버를 Select 해오고, 이후 팀을 가져오게된다.
그렇다면 N명의 팀을 하나씩 또 조회하게되면 N번을 또 조회한다는얘기. 그래서 나온말이 N+1 문제이다.
이러한 쿼리를 남발하는 문제를 해결하기 위해 해결방안으로 사용하는것중 하나가 fetch join이다.

 

Fetch join과 일반 join의 차이

  • fetch join : 결과를 반환할때 연관관계를 무시하고 Select절에 명시된 entity만 조회하여 반환한다.
  • 일반 join : 결과를 반환할때 연관된 entity들도 함께 반환한다.

Fetch Join의 Distinct

fetch join을 사용했을때 중복된 Row가 생기는 경우가 있다.

이때 JPQL에서도 Distinct - SQL에서도 지원하는 문법으로 중복결과 제거 문법을 사용할 수 있다.

select distinct t From Team t join fetch t.members;

 

기본을 알아야 응용을 할수가있다.!!!!

SQL만 사용하다가 JPA를 보니 새로운 개념들이 참 많은것 같다..

반응형