JPA를 통해 회사에서 SI용 탬플릿을 만들때 공부했던 것입니다.
팀장님과 제가 테이블 관계가 1:N 의 경우 EAGER(팀장) vs LAZY(나) 전략중 무엇을 기본 전략으로 고를지 논의중이었을때. 이 글을 통하여 팀장님을 설득에 성공하여 LAZY 전략을 기본 전략으로 가지고 갈수 있도록 하였습니다.
제가 LAZY 전략을 기본 전략으로 해야한다고 주장했던 이유는 이전 경험 때문이었습니다.
때는 이전 Mybatis 탬플릿으로 만들어진 프로젝트의 쿼리 성능 최적화할때였고. 쿼리중 하나가 과도한 join으로 인해 데카르트 곱 문제가 발생하여 실제 정보보다 훨씬 많은 양의 데이터 통신을 하여서 쿼리 시간이 20초를 넘기는 괴랄한 성능이 나왔기 때문이었습니다. (캐싱으로 쿼리 시간을 극복했던 쿼리)
이를 최적화하려 한번에 모든 테이블을 JOIN하여 가져오기 보다 외래키를 모아서 ~ in (...)을 사용하는 쿼리 몇개로 나누어서 HashMap을 통하여 객체를 생성해주었더니 무려 50% 나 수행시간이 줄이는 결과를 경험했습니다.
물론 모든 상황에서 Batch Fetching 성능이 좋은 것은 아니지만, 1:N 의 관계가 많을 경우에는 데이터의 양이 많아지면 많이 질수록 Join Fetching 보다 좋은 성능을 나타냅니다.
SPRING DATA JPA (HIBERNATE)는 전역적으로 사용할 때 default_batch_fetch_size 를 반드시 설정해 줘야 합니다.
여러분들도 어떤 경우에 그리고 왜 Eager(Join Fetch) 보다 LAZY(Batch Fetching)이 성능이 더 좋은지 아래의 글들을 한번 읽어보시길 바랍니다.
[번역] Batch Fetching - 객체 그래프 로딩을 최적화 하기 (JPA/ECLIPSELINK) narusas's blog