엔티티 영속성 전이 문제를 어찌어찌 해결한 후 한시름 놨다고 생각할 때쯤 쿼리 로그를 보니 뭔가 이상했다.
위 글(영속성 전이 해결 글)에서는 편의상 해결한 후의 쿼리 사진을 사용하였다.
무수한 SELECT 요청이 날아가고 있었고, 딱 보자마자 N+1 문제라는 느낌이 확 왔다.
그런데 사실 그도 그럴 것이 기존에 멤버가 질문한 개수를 구하는 로직은 이렇게 작성되어 있었다.
멤버의 history를 구하고 해당 history의 question을 다 구해와서 size를 별도로 구하기 때문에 history에 포함된 question을 다 구하기 위해 쿼리가 history당 1개씩 즉 해당 테스트에서는 100번이나 나간 것이었다.
그래서 결국 JPQL을 사용하여 join을 사용한 COUNT 쿼리를 직접 작성하였다.
이렇게 바꾼 후 쿼리는
깔끔하게 한줄로 변했고, 시간은...
사실 시간은 별로 안 변했다. 1074ms에서 964ms 정도로 살짝 줄긴 했는데, 나가는 쿼리의 숫자가 줄어들었는 게 더 의미가 있다고 생각한다! 그만큼 디비에 부하가 줄어들겠지...
JPA를 책으로만 공부하다가 이번에 프로젝트에서 만나보니까 정말 대규모 트래픽을 가진 서비스에서 N+1 문제가 발생하면 정말 치명적일 것 같다고 느꼈다. 이런 엔티티에 대해 Lazy 하게 혹은 Eager 하게, 영속성 전이를 어떻게 처리할지 그리고 이러한 설정으로 인해 쿼리가 어떻게 나갈지 등에 대해 깊게 고민하며 설계하는 것이 중요할 것 같다.