Back-end/Spring

[SpringBoot] 페치 조인 (Fetch Join)

poppy 2022. 4. 6. 14:28
반응형

페치 조인이란?

- SQL 조인 종류가 아니다

- JPQL에서 성능 최적화를 위해 제공하는 기능이다

- 연관된 엔티티나 컬렉션을 SQL 한 번에 함께 조회하는 기능이다

- join fetch 명령어 사용한다

 

엔티티 페치 조인

회원을 조회하면서 연관된 팀도 함께 조회한다. 쿼리는 다음과 같다.

select m from Member m join fetch m.team (SQL 1번)

SQL을 보면 회원 뿐만 아니라 팀도 함께 조회된다. 회원 조회 → 팀 조회로 SQL 2번 나가는 것을 페치 조인을 사용하면 쿼리가 나가는 횟수를 줄일 수 있다.

Member의 team에 Lazy 로딩이 설정되어 있어도 페치 조인이 우선시된다.

String jpql = "select m from Member m join fetch m.team"; 
List<Member> members = em.createQuery(jpql, Member.class).getResultList();

for (Member member : members) {
	//페치 조인으로 회원과 팀을 함께 조회해서 지연 로딩X
 	System.out.println("username = " + member.getUsername() + ", " + "teamName = " + member.getTeam().name()); 
}

 

컬렉션 페치 조인

일대다 관계에서 사용하는 페치 조인을 컬렉션 페치 조인이라고 한다. 쿼리는 다음과 같다.

select t from Team t join fetch t.members where t.name = ‘팀A'

String jpql = "select t from Team t join fetch t.members where t.name = '팀A'" 
List<Team> teams = em.createQuery(jpql, Team.class).getResultList();

for(Team team : teams) { 
	System.out.println("teamname = " + team.getName() + ", team = " + team); 
 	for (Member member : team.getMembers()) { 
 		//페치 조인으로 팀과 회원을 함께 조회해서 지연 로딩 발생 안함
 		System.out.println(“-> username = " + member.getUsername()+ ", member = " + member); 
 	} 
}

 

근데 컬렉션을 페치 조인을 하면 일대다 관계이기 때문에 데이터가 뻥튀기 된다. 즉, 중복 데이터가 조회된다. 

SQL의 DISTINCT는 중복된 결과를 제거하는 명령이다.

 

[JPQL의 DISTINCT 2가지 기능 제공]

1. SQL에 DISTINCT를 추가

2. 애플리케이션에서 엔티티 중복 제거

 

DISTINCT를 사용한 쿼리는 다음과 같다. select distinct t from Team t join fetch t.members where t.name = ‘팀A’

SQL에 DISTINCT를 추가하지만 데이터가 다르므로 SQL 결과에서 중복 제거에 실패한다.

 

페치 조인의 특징과 한계

- 페치 조인 대상에는 별칭을 줄 수 없다 (하이버네이트는 가능, 가급적 사용X)

- 둘 이상의 컬렉션은 페치 조인 할 수 없다

- 컬렉션을 페치 조인하면 페이징 API(setFirstResult, setMaxResults)를 사용할 수 없다 (일대일, 다대일 같은 단일 값 연관 필드들은 페치 조인해도 페이징 가능) 

- 연관된 엔티티들을 SQL 한 번으로 조회할 수 있다 → 성능 최적화

- 엔티티에 직접 적용하는 글로벌 로딩 전략보다 우선한다 @OneToMany(fetch = FetchType.LAZY) // 글로벌 로딩 전략 

- 실무에서 글로벌 로딩 전략은 모두 지연 로딩으로 설정해야 한다

- 최적화가 필요한 곳은 페치 조인 적용하는 것이 좋다

 

 

 

반응형