지난번 포스트에서 fetch join이 오히려 성능을 떨어트리는 원인을 찾아봤습니다. 이번 포스트에서는 해당 문제점을 해결하여 실질적인 성능향상을 이뤘던 내용을 정리해보려합니다.
페치조인이 성능을 떨어트린 이유는 아래 포스트 참고
https://velog.io/@junho_99/JPA-Fetch-Join-%EC%BF%BC%EB%A6%AC-%EB%B6%84%EC%84%9D%EC%9C%BC%EB%A1%9C-%EC%84%B1%EB%8A%A5-%EB%B9%84%EA%B5%90
문제를 요약하면
1. 페치조인으로 유저와 해당유저 게시글을 한번에 가져옴
2. DISTINCT + 정렬 + 페이징 등을 페치조인 쿼리와 함께 사용하면 조인으로 늘어난 row에 대한 계산을 진행해야하므로 성능 저하됨
3. 1:N 관계에서의 페치조인은 row를 N개만큼 중복생성함
위의 문제들을 해결한뒤에
페치조인 사용 전 vs 후 성능 비교를 시도했지만, 성능 차이가 거의 없었습니다.
Post ↔ MediaFile은 Lazy 로딩으로 개별 조회 → N+1 발생 MediaFile 조회 시 WHERE post_id IN (...) 사용 Post ↔ MediaFile도 Fetch Join아래의 그래프는 왼쪽부터
쿼리최적화X ----------- 페치조인+IN절 사용 ------- 캐쉬까지 적용

P50, P95, P99 성능지표

페치조인을 사용했을때와 사용하지 않았을때 성능차이가 거의 20~30배가 났습니다.
nGrinder 부하테스트 결과

| 전략 | 장점 | 단점 |
|---|---|---|
| Fetch Join | 직관적이고 한 쿼리로 해결 | 데이터가 많으면 row 폭증 |
| IN 절 | 대량 데이터, 정렬/페이징에 유리 | 코드가 조금 복잡, 쿼리 2번 |
User ↔ Post는 Fetch JoinPost ↔ MediaFile은 IN 절 기반 조회 + 메모리에서 주입