페치 조인은 중요하다고 소문이 자자하다.
대체 어떤 면이 좋길래 그렇게 중요하다고 하는지 알아보자.
페치 조인이란?
JPQL에서 성능 최적화를 위해 따로 제공하는 기능이다.
연관된 엔티티나 컬렉션을 한번의 SQL로 조회하는 기능이다.
SQL의 조인 종류 중 하나는 아니다.
[JPQL]
select m from Member m join fetch m.team
[SQL]
SELECT M.*, T.* FROM MEMBER M INNER JOIN TEAM T ON M.TEAM_ID=T.ID
엔티티 페치 조인 = 다대일 관계의 페치 조인
컬렉션 페치 조인 = 일대다 관계의 페치 조인
이 경우에는 위 사진처럼 하나의 팀에 여러 멤버 ROW가 들어가기 때문에 팀이 두번 조회되어 저장된다.
이는 쿼리 결과로 보면 같은 결과를 두번 중복되어 조회된 것으로 보인다.
이는 JPQL의 DISTINCT 기능을 통해 해결할 수 있다.
JPQL의 DISTINCT 키워드는 두가지 기능을 수행한다.
- SQL에서의 DISTINCT 수행 -> SQL문에 추가해 수행
- 엔티티 중복 제거
- 같은 PK를 가진 엔티티를 제거해 중복을 없앤다.
페치 조인과 일반 조인의 차이
일반 조인은 실행 시 자기만 조회한다.
[JPQL]
select t
from Team t join t.members m
where t.name = '팀A';
[SQL]
SELECT T.*
FROM TEAM T
INNER JOIN MEMBER M ON T.ID=M.TEAM_ID
WHERE T.NAME = '팀A';
-> 팀만 조회한 조인문
페치 조인은 싹 다 한번에 조회한다.
[JPQL]
select t
from Team t join fetch t.members
where t.name = '팀A'
[SQL]
SELECT T.*, M.*
FROM TEAM T
INNER JOIN MEMBER M ON T.ID=M.TEAM_ID
WHERE T.NAME = '팀A'
-> 한번의 쿼리문으로 팀이랑 멤버 둘 다 조회해오는 것을 볼 수 있다.
페치 조인의 특징과 한계
- 페치 조인 대상에는 별칭을 줄 수 없다.
- 둘 이상의 컬렉션은 페치 조인할 수 없다.
- 컬렉션(다대일)을 페치 조인하면 페이징 api를 사용할 수 없다.
- 중복된 값이 들어올 경우에도 다 갯수로 카운트해버리기 때문.
- 연관된 엔티티들을 한번의 SQL로 조회해 성능 최적화
- 엔티티에 직접 적용하는 글로벌 로딩 전략보다 우선순위를 가진다.
- FetchType.LAZY 같은거.
- 실무에서 글로벌 로딩 전략은 모두 지연 로딩으로 하고, 최적화가 필요한 곳만 페치 조인을 적용.
- 엔티티 모양이 아닌 결과를 내야한다면 일반 조인을 사용해 필요한 데이터만 조회, DTO로 반환하는 것이 효과적이다.
'Spring > 이론' 카테고리의 다른 글
[JPA] 준영속 엔티티란? 더티체킹이란? (0) | 2023.09.14 |
---|---|
동적 쿼리 VS 정적 쿼리 차이, 예시 (0) | 2023.09.06 |
[JPA] JPQL 경로 표현식 (0) | 2023.08.02 |
[JPA] JPQL 문법과 기능 (0) | 2023.07.26 |
JPA - 값 타입 (0) | 2023.07.07 |