본문 바로가기

내일 배움 캠프

2024-01-25

오늘은 프로젝트 22일 차이다.

프로젝트를 진행하면서 기존에 메인페이지에서 조회하는 공연 전체 조회를 성능 최적화 하기 위해 준비했다.

오프셋 페이지네이션에서 성능 최적화를 하면서 Page방식에서 커서 방식으로 변경했기 때문에 기존에 있던 코드와 비교를 진행했다. 그러기 위해서는 AOP를 추가해야 하는데 다음과 같이 추가했다. 이 AOP는 쿼리가 실행되는 시간을 보여준다.

package com.sparta.ticketauction.global.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class QueryExecutionAspect {

    private static final Logger logger = LoggerFactory.getLogger(QueryExecutionAspect.class);
    private ThreadLocal<Long> startTime = new ThreadLocal<>();

    @Before("execution(* com.sparta.ticketauction.domain.goods.repository.GoodsRepositoryCustomImpl.*(..))")
    public void beforeQueryExecution(JoinPoint joinPoint) {
       startTime.set(System.currentTimeMillis());
    }

    @After("execution(* com.sparta.ticketauction.domain.goods.repository.GoodsRepositoryCustomImpl.*(..))")
    public void afterQueryExecution(JoinPoint joinPoint) {
       long timeTaken = System.currentTimeMillis() - startTime.get();
       startTime.remove(); // ThreadLocal 정리

       logger.info("Execution of {} took {} ms", joinPoint.getSignature(), timeTaken);
    }
}
 
implementation 'org.springframework.boot:spring-boot-starter-aop'

이렇게 추가를 진행하고 테스트

쿼리 실행시간 비교 끝에 있는 데이터 보여주기 size 20
2024-01-25T 16:17:33.859+09:00  INFO 26360 --- [nio-8080-exec-1] c.s.t.global.aop.QueryExecutionAspect    : Execution of List com.sparta.ticketauction.domain.goods.repository.GoodsRepositor yCustomImpl.findAllByGoodsAndCategoryName(Long, int, String) took 20 ms

 

2024-01-25T 16:17:54.311+09:00  INFO 26360 --- [nio-8080-exec-2] c.s.t.global.aop.QueryExecutionAspect    : Execution of Slice com.sparta.ticketauction.domain.goods.repository.GoodsRepositor yCustomImpl.findAllByGoodsPageAndCategoryName(Pageable, String) took 42 ms

 

첫 페이지 전체 조회 시 size 9500

 

2024-01-25T 16:18:52.781+09:00  INFO 26360 --- [nio-8080-exec-4] c.s.t.global.aop.QueryExecutionAspect    : Execution of Slice com.sparta.ticketauction.domain.goods.repository.GoodsRepositor yCustomImpl.findAllByGoodsPageAndCategoryNameSlice(Pageable, String) took 107 ms

2024-01-25T 16:19:43.188+09:00  INFO 26360 --- [nio-8080-exec-6] c.s.t.global.aop.QueryExecutionAspect    : Execution of List com.sparta.ticketauction.domain.goods.repository.GoodsRepositor yCustomImpl.findAllByGoodsAndCategoryName(Long, int, String) took 414 ms

 

카테고리 가있을 때의 조회

2024-01-25T 16:21:42.668+09:00  INFO 26360 --- [nio-8080-exec-2] c.s.t.global.aop.QueryExecutionAspect    : Execution of Slice com.sparta.ticketauction.domain.goods.repository.GoodsRepositor yCustomImpl.findAllByGoodsPageAndCategoryNameSlice(Pageable, String) took 7 ms
2024-01-25T 16:21:12.557+09:00  INFO 26360 --- [io-8080-exec-10] c.s.t.global.aop.QueryExecutionAspect    : Execution of List com.sparta.ticketauction.domain.goods.repository.GoodsRepositor yCustomImpl.findAllByGoodsAndCategoryName(Long, int, String) took 9 ms

 

size가 작을 시에는 단건 조회 시에는 확실하게 커서 기반이 쿼리 실행 속도가 빠르다.
큰 기반으로 조회시에는 Slice가 빠르다.

근데 테스트를 진행하다 보니 애초에 잘못된 문제가 있다는 것을 깨달아 버렸다. 바로 N+1문제 때문에 정확한 측정이 아니었던 것.....
내일은 쿼리를 대폭 수정해서 N+1문제를 수정할 것이다.

'내일 배움 캠프' 카테고리의 다른 글

2024-01-29  (0) 2024.01.30
2024-01-26  (1) 2024.01.27
2024-01-24  (0) 2024.01.25
2024-01-23  (0) 2024.01.23
2024-01-22  (0) 2024.01.23