본문 바로가기
Spring

페치조인(Fetch Join)

by asdft 2024. 2. 20.

참고

https://kihwan95.tistory.com/12

 

페치조인(fetch Join )이란

페치(fetch)조인은 SQL에서 사용하는 조인의 종류는 아니고 JPQL에서 성능 최적화를 위해 제공하는 기능입니다. 이것은 연관된 엔티티나 컬렉션을 한 번에 같이 조회하는 기능인데 join fetch 명령어

kihwan95.tistory.com

 

페치 조인 (Fetch Join)은

SQL에서 사용하는 조인의 종류는 아니고 JPQL에서 성능 최적화를 위해 제공하는 기능입니다.
이것은 연관된 엔티티나 컬렉션을 한 번에 같이 조회하는 기능인데 join fetch 명령어로 사용할 수 있습니다.

 

 

JPQL은 결과를 반환할 때 연관관계까지 고려하지 않는다. 단지 SELECT 절에 지정한 엔티티만 조회할 뿐이다
따라서 Member엔티티만 조회를 해오고, 지연 로딩으로 설정되어 있어서 Team엔티티는 프록시 객체로 가져옵니다.
이후 Team엔티티의 정보를 조회하면 ex)member.getTeam().getName()
Team엔티티의 정보를 위한 SELECT 쿼리가 DataBase에 별도로 나갑니다. (N + 1 문제)

이러한 문제를 해결하기 위해 드디어 페치 조인을 사용합니다.

 

이런 페치 조인을 사용하면 SQL 한 번으로 연관된 엔티티들을 함께 조회할 수 있어서 SQL 호출 횟수를 줄여 성능을 최적화할 수 있습니다.

최적화를 위해 글로벌 로딩 전략을 EAGER(즉시 로딩)로 설정하면 애플리케이션 전체에서 항상 즉시 로딩이 일어난다.  (사용하지 않는 엔티티를 자주 로딩하므로 성능에 악영향을 미칠 수 있다.)

따라서 글로벌 로딩 전략은 지연 로딩으로 설정하고 최적화가 필요하면 앞에서와 같이 페치 조인(fetch join)을 적용하는 것이 효과적이다.

 

 

페치 조인의 한계

 

1. 페치 조인 대상에는 별칭을 줄 수 없다.
- JPA 표준에서는 지원하지 않지만 하이버네이트를 포함한 몇몇 구현체들은 페치 조인에 별칭을 지원하지만 별칭을 잘못 사용하면 연관된 데이터 수가 달라져서 데이터 무결성이 깨질 수 있으므로 사용하지 않는 것이 좋다.

 

2. 둘 이상의 컬렉션을 페치 할 수 없다.
- 구현체에 따라 되기도 하는데 컬렉션 * 컬렉션의 카테시안 곱이 만들어지므로 주의해야 한다. 하이버네이트를 사용하면 예외가 발생한다.

 

3. 컬렉션을 페치 조인하면 페이징 API(setFirstResult, setMaxResults)를 사용할 수 없다.
- 컬렉션(일대다)이 아닌 단일 값 연관 필드(일대일, 다대일)들은 페치 조인을 사용해도 페이징 API를 사용할 수 있다.
- 하이버네이트에서 컬렉션을 페치 조인하고 페이징 API를 사용하면 경고 로그를 뱉는다.

--컬렉션을 페치 조인하고 페이징API를 사용하면 메모리에서 페이징 처리를 진행한다.
--데이터가 적으면 상관없겠지만 데이터가 많으면 성능 이슈와 메모리 초과 예외가 발생할 수 있기 때문이다.