쿼리 성능 개선기

혁콩·2024년 10월 8일

모두의 음악

목록 보기
16/17
post-thumbnail

들어가기에 앞서

모두의 음악은 네이버 밴드와 같은 커뮤니티 기반의 게시판 서비스예요.

유명 커뮤니티인 인벤루리웹에서 추출한 총 47만개의 게시글 데이터를 반복해서 삽입, 총 300만개의 게시판 데이터를 삽입했습니다.

이제 게시판이 제대로 동작하는지 확인해볼까요?

페이징 쿼리 개선

시작하자마자 문제가 발생했네요. 일반적인 게시글 조회에 총 4분 51초가 걸렸습니다.

쿼리는 의도한대로 발생하는 것 같아요.

다만, 단 한번의 요청만으로 서버의 부하가 엄청나게 상승했습니다. 가장 많이 발생할 요청이기에, 동시 접속자가 10명만 되어도 서버가 터질 것 같아요.


QueryDSL의 페이징 쿼리를 확인해봤습니다. 아차, 여기서 실수가 있었네요.

JPA의 fetch-join을 사용해 JOINPagination 을 하나의 쿼리에서 수행할 시 모든 데이터를 메모리에 올린 후 자체적으로 페이징을 처리합니다.

이 때문에, 3백만건의 데이터를 모두 자바 어플리케이션에서 처리해 문제가 발생한 것 같아요.


페이징과 실제 조회 쿼리를 분리했습니다. 페이징 쿼리에서 조회할 데이터들을 찾고, 찾은 데이터들만 조인을 통해 조회하는거죠.


쿼리를 분리함으로써 4분 51초에서 0.1초로 응답 시간이 개선됐네요. 서버에도 비정상적인 부하가 발생하지 않을거예요.

글자수 제한


페이징을 테스트하던 중 데이터 크기가 급격히 늘어났어요. 이유를 보니 엄청난 장문의 글이 포함되어있네요. 가장 긴 게시글을 찾아보니 78만자의 내용을 갖고 있네요.


게시글 목록에서 모든 데이터를 노출시키지 않을 것이기 때문에 모든 데이터를 보내는 건 불필요하다고 생각했습니다. 이에, 미리보기를 위한 내용 300자만 보내는 것으로 결정했어요. 해당 게시글을 단건으로 조회할 때 모든 데이터를 보내주는거죠.

추가적으로 DTO 반환을 채용함으로서 불필요해진 fetch-join과 필요 없던 group 테이블 조인을 제거해줬어요.

자, 이제 바뀐걸 확인해볼까요?

데이터 크기가 168kb -> 4.4kb로 164kb(97.3%) 감소했고, 응답 시간 또한 115ms -> 71ms로 44ms 감소했네요.

profile
아는 척 하기 좋아하는 콩

0개의 댓글