개요
JPA를 사용하다보면 가장 흔하게 발생하는 문제가 바로 "N+1"문제입니다.
N+1문제를 해결하기 위한 방법은 여러가지이지만 주로 Fetch Join을 사용하고는 합니다.
본 글에서는 왜 많은 방법중에서 Fetch Join을 주로 사용하는지에 대해서 알아본 내용을 정리하고자 합니다.
Fetch Join의 장점
1. 즉시 로딩과 명시적 제어
Fetch Join은 JPQL 쿼리에서 명시적으로 사용되기 때문에, 어떤 연관 데이터를 즉시 로딩할지 명확하게 정의할 수 있습니다. 이는 @EntityGraph나 @BatchSize와 같은 방법들에 비해 제어가 더 직관적입니다.
SELECT h FROM HubPath h JOIN FETCH h.departureHub JOIN FETCH h.arrivalHub
위와 같이 쿼리 안에서 어떤 연관 데이터를 Fetch Join할지를 명확하게 지정할 수 있습니다. 따라서 원하는 시점에 원하는 데이터를 가져올 수 있는 장점이 있습니다.
3. 유연성
Fetch Join은 여러 관계를 동시에 페치할 수 있어, 복잡한 엔티티 관계에서도 유연하게 사용할 수 있습니다. 필요한 관계만 명시적으로 포함하거나 제외할 수 있어 성능 최적화에 도움이 됩니다.
예를 들어, @EntityGraph는 한정된 범위에서만 사용할 수 있는 반면, Fetch Join은 복잡한 관계를 다루는 JPQL 쿼리에서 더 폭넓게 활용할 수 있습니다.
4. SQL 쿼리의 투명성
Fetch Join을 사용하면 결국 생성되는 SQL 쿼리를 명확히 볼 수 있습니다. 이는 성능 최적화를 할 때 매우 유용한데, 개발자는 JPQL 쿼리에서 직접 어떤 테이블들이 조인되고 어떤 데이터를 가져오는지 직관적으로 파악할 수 있습니다.
@EntityGraph나 @BatchSize의 한계
- @EntityGraph
- 선언적이고 간편하지만, 복잡한 쿼리에서는 사용이 제한적입니다. 특히, 조건부로 연관 엔티티를 가져와야 할 때는 Fetch Join만큼
유연하지 않습니다.
- 선언적이고 간편하지만, 복잡한 쿼리에서는 사용이 제한적입니다. 특히, 조건부로 연관 엔티티를 가져와야 할 때는 Fetch Join만큼
- @BatchSize
- N+1 문제를 완화해줄 수는 있지만, Fetch Join처럼 한 번의 쿼리로
모든 연관 데이터를 가져오는 것이 아니라, 다수의 SQL 쿼리를 병렬로 처리하여 성능을 향상시키는 방식입니다. 이 경우 쿼리 수가 여전히 줄어들지 않을 수 있습니다.
- N+1 문제를 완화해줄 수는 있지만, Fetch Join처럼 한 번의 쿼리로
결론적으로 Fetch Join은 제어가 명확하고 직관적이며, 복잡한 엔티티 관계에서도 유연하게 적용 가능하다는 장점 때문에 많이 사용됩니다. 또한 N+1 문제를 해결하는 데 가장 직접적이고 효율적인 방법이기 때문에, 대부분의 경우 성능 최적화를 위해 Fetch Join이 선호되는 것입니다.
'TIL,일일 회고' 카테고리의 다른 글
[TIL, 일일 회고] 2024.09.22 - 대용량 데이터 에러 해결 트러블 슈팅 (0) | 2024.09.22 |
---|---|
[TIL, 일일 회고] 2024.09.21 - N+1 문제 해결 및 성능 최적화: HubPath 조회 트러블슈팅 (0) | 2024.09.22 |
[TIL, 일일 회고] 2024.09.19 - DDL 자동 생성하기 (0) | 2024.09.19 |
[TIL, 일일 회고] 2024.09.18 - PostgreSQL에서 문자열 길이 초과 오류 해결: @Lob 어노테이션 (0) | 2024.09.18 |
[TIL, 일일 회고] 2024.09.17 - Zipkin 분산 트레이싱 실패 원인 분석 (0) | 2024.09.17 |