게시글 조회 쿼리 속도 개선

Kuno17·2023년 4월 22일
0

TIL/WIL

목록 보기
35/38
post-thumbnail
post-custom-banner

문제점

메서드의 진행속도를 측정하는 AOP를 만들어서 측정하려는 메서드에 적용시킨 결과 게시글을 조회하는 메서드의 속도가 기대치보다 낮은점을 알 수 있었다.

원인은 다음 3가지 정도로 확인할 수 있었다.

  1. 연관된 테이블을 모두 불러오는 쿼리 발생.
  2. 받아온 정보를 다시 Paging 처리해서 반환.
  3. 처음에 모든 게시글 데이터를 조회하는 점.

코드 개선

속도를 개선할 방향으로 다음과 같은 3가지 방향성을 고민할 수 있었다.

  1. QueryDsl을 이용해서 테이블을 join시켜서 발생 쿼리를 줄일 수 있을것.
  2. 자료를 찾아올 때 (Query를 실행할 때) Paging처리를 바로 진행할 것.
  3. 불필요한 코드를 정리하고 시간복잡도가 높은 부분(이중 for문 과 같은점)이 있다면 수정할 것.

Code

현재 검색기능을 구현하기위해 셋팅을 마친 QueryDsl을 이용해서 수정을 해줄 수 있었다.

    @Override
    public List<Post> find(String category, Pageable pageable, Double lat, Double lng, Sort sort) {
        List<OrderSpecifier<?>> orderSpecifiers = new ArrayList<>();
        QReview review = QReview.review1;

        switch (sort) {
            case DISTANCE ->
                    orderSpecifiers.add(Expressions.asNumber(Expressions.template(Double.class, distanceQuery(lat, lng))).asc());
            case STAR -> {
                NumberExpression<Double> avgStar = review.star.avg().coalesce(0.0);
                orderSpecifiers.add(avgStar.desc());
            }
            case REVIEW -> orderSpecifiers.add(post.reviews.size().desc());
            default -> throw new IllegalArgumentException("Invalid sort value: " + sort);
        }

        return queryFactory
                .select(post)
                .from(post)
                .leftJoin(post.reviews, review)
                .where(post.category.eq(category))
                .groupBy(post)
                .orderBy(orderSpecifiers.toArray(new OrderSpecifier[0]))
                .offset(pageable.getOffset())
                .limit(pageable.getPageSize())
                .fetch();
    }

알게된 점

  1. 일반적인 쿼리문을 작성하는 방법과는 다르다.
  2. leftJoin()을 사용하여 연관된 엔티티를 함께 로딩하지 않더라도, Join 조건에 매칭되는 엔티티의 PK(FK) 값을 가진 컬럼의 데이터를 가져올 수 있다. 이를 통해서 N+1문제를 해결할 수 있다.
  3. 쿼리를 작성하는 방법은 정말 다양하고, 어떤게 최적일 수 있는지 수정시 어떤 변화가 생기는지 반드시 확인이 필요하다.

최적화 결과

코드를 수정하고 다음과 같은 방법으로 메서드 속도변화를 확인했다.

  1. 기존 상태에서 측정
  2. 이중for문과 같은 잘못된 부분을 수정하고 측정.
  3. 조회 쿼리를 위와같은 코드로 수정하고 측정.

아래 표와 그래프로 정리되었으며 약 2배 이상의 속도개선이 이루어졌다.

profile
자바 스터디 정리 - 하단 홈 버튼 참조.
post-custom-banner

0개의 댓글