0. 배경
게시글 불러오는 쿼리를 개선하기 위해 좋아요 데이터를 많이 넣어보다가 좋아요 데이터가 많아지면 조회 속도가 매우 느려지는 것을 확인했고, 더 많은 데이터를 넣었을 때 Java heap space 에러가 발생하여 해결 방법을 정리하였습니다.
1. 현재 상황
1.1 Post Entity, PostLike Entity
1.2 PostService - getPost()
1.3 PostResponse.of()
1.4 게시글에 좋아요가 478,416개 있는 상황에서 단건 조회 응답 시간 - 9s
1.5 발생하는 쿼리
PostLike를 전체 조회하는 것을 확인할 수 있습니다.
2. 발생 원인
2.1 PostResponse 코드 문제
발생원인은 PostResponse에서 찾을 수 있습니다.
post.getPostLikes().size() 쿼리에서 문제가 발생합니다.
2.2 이유
Post와 연관되어있는 PostLike를 DB에서 모두 조회한 후, list에 담고 해당 list의 사이즈를 반환하기 때문입니다.
저는 .size()를 사용하면 count쿼리가 발생하는 것으로만 생각했는데, 해당 상황을 겪고 발생하는 쿼리를 보고 문제가 여기서 발생했음을 알 수 있었습니다.
PostLike를 모두 select하여 47만건을 가져오기 때문에 시간이 매우 오래 걸리는 것을 알 수 있습니다.
로컬인 경우 9초가 걸렸지만 게시글을 불러올 수 있었습니다.
하지만 배포 환경에서는 심각한 장애가 발생합니다.
2.3 OutOfMemoryError
로컬 환경에 비해 배포 환경은 용량이 작습니다.
따라서 힙 스페이스 부족으로 OutOfMemoryError라는 치명적인 장애가 발생할 수 있습니다.
3. 해결 방법
3.1 count 쿼리를 사용
JPA Repository에서 직접 Count 쿼리를 만들어서 Response 값에 넣어주는 방법을 선택했습니다.
count 쿼리를 이용하여 불필요한 select을 최소화 하였습니다.
3.2 결과
눈에 띄게 개선 되었음을 알 수 있습니다.
4. 결론
로컬 환경
좋아요 개수가 478,416일 경우
9s -> 763ms로 로컬 환경에서 8초 이상 속도가 개선 되었음을 확인할 수 있었습니다.
좋아요 개수가 178,416일 경우
3.6s -> 160ms로 3.5초 이상 속도가 개선되었음을 알 수 있습니다.
배포 환경
배포 환경에서는 OutOfMemoryError가 발생하였던 것을 해결할 수 있었습니다.
좋아요 개수가 178,416개일 때
5ms -> 200ms로 4.8초 이상 개선되었음을 알 수 있습니다.