TIL/김영한의 자바 ORM 표준 JPA 프로그래밍 - 기본편
객체지향 쿼리 언어 - 페치 조인
minOE
2025. 7. 10. 14:51
728x90
페치 조인(fetch join)
- SQL 조인 종류 X
- JPQL에서 성능 최적화를 위해 제공하는 기능
- 연관된 엔티티나 컬렉션을 SQL 한 번에 함께 조회하는 기능
- join fetch 명령어 사용
- 페치 조인 ::= [ LEFT [OUTER] | INNER ] JOIN FETCH 조인경로
엔티티 페치 조인
- 회원을 조회하면서 연관된 팀도 함께 조회(SQL 한 번에)
- 다음 JPQL은 Hibernate 6에서 실행 시 아래와 같은 SQL로 변환됩니다
-- JPQL select m from Member m join fetch m.team -- Hibernate 6에서 변환된 SQL (로깅 기준) select m1_0.id, m1_0.age, t1_0.id, t1_0.name, m1_0.username from Member m1_0 join Team t1_0 on t1_0.id = m1_0.TEAM_ID
컬렉션 페치 조인과 DISTINCT
- 일대다 관계, 컬렉션 페치 조인
- 다음 JPQL은 Hibernate 6에서 실행 시 아래와 같은 SQL로 변환됩니다
-- JPQL select distinct t from Team t join fetch t.members where t.name = '팀A' -- Hibernate 6 SQL (로그 출력 기준) select distinct t1_0.id, m1_0.TEAM_ID, m1_0.id, m1_0.age, m1_0.username, t1_0.name from Team t1_0 join Member m1_0 on t1_0.id = m1_0.TEAM_ID where t1_0.name = '팀A'
- SQL의 DISTINCT는 중복된 결과를 제거하는 명령
- JPQL의 DISTINCT 2가지 기능 제공
1) SQL에 DISTINCT를 추가
2) 애플리케이션에서 엔티티 중복 제거
페치 조인과 일반 조인의 차이
1. 일반 조인 (join)
-- JPQL select distinct t from Team t join t.members m where t.name = '팀B' -- Hibernate 실행 SQL (쿼리 1) select distinct t1_0.id, t1_0.name from Team t1_0 join Member m1_0 on t1_0.id = m1_0.TEAM_ID where t1_0.name = '팀B' -- 추가 SQL (getMembers() 호출 시 지연 로딩 발생) select m1_0.TEAM_ID, m1_0.id, m1_0.age, m1_0.username from Member m1_0 where m1_0.TEAM_ID = ?
- Team만 select 대상이므로, members는 로딩되지 않음
- team.getMembers() 호출 시점에 추가 SQL 실행됨 (지연 로딩, Lazy)
- 쿼리 2번 실행됨 (N+1 가능성 있음)
2. 페치 조인 (join fetch)
-- JPQL select distinct t from Team t join fetch t.members m where t.name = '팀B' -- Hibernate 실행 SQL (쿼리 1회) select distinct t1_0.id, m1_0.TEAM_ID, m1_0.id, m1_0.age, m1_0.username, t1_0.name from Team t1_0 join Member m1_0 on t1_0.id = m1_0.TEAM_ID where t1_0.name = '팀B'
- Team과 연관된 Member를 한 번의 SQL로 모두 로딩
- getMembers() 호출해도 추가 쿼리 발생하지 않음
- 성능 효율적 , N+1 방지
✅ 정리 비교
페치 조인은 연관 엔티티까지 한 번에 가져와 N+1 문제를 해결하고 성능을 최적화할 수 있습니다.
일반 조인은 연관 객체를 즉시 로딩하지 않기 때문에, 연관 데이터를 사용할 경우추가 쿼리가 발생할 수 있습니다.
출력은 같아 보여도 쿼리 수와 성능은 다릅니다.
728x90