카테고리 없음

SQL 성능 개선 포트폴리오 예시

gw1 2026. 2. 19. 02:44

주문 목록 조회 SQL 튜닝

주문 목록 조회 SQL 튜닝

MySQL innoDB 8.0기준다른 DB는 결과가 다를 수 있음CREATE TABLE `orders` ( `id` bigint unsigned NOT NULL AUTO_INCREMENT, `user_id` int DEFAULT NULL, `order_status` varchar(30) NOT NULL DEFAULT 'CREATED', `order_date` datetime DEFAULT NULL, `pric

gw7193.tistory.com

 
들어가기 앞서
 
포트폴리오 작성 방식을 보여주기 위함이지, SQL 튜닝 내용에 집중하실 필요 없습니다.
 
문제 정의를 확실히 해서 이게 왜 문제인지 당장 해결해야 하는 이슈가 맞는지

여러가지 방안을 비교해서 어떤게 나은지

직접 테스트

결론

구조를 봐주세요


 
제목 : 주문 조회 SQL 성능 지연 개선
 
문제 정의 :

SELECT
    *
FROM
    test.orders
WHERE
    order_date BETWEEN '2025-03-01 00:00:00'
                  AND '2025-03-31 23:59:59'
ORDER BY
    sum_price DESC,
    id
LIMIT
    10, 10;

 

테스트 127.7초
테스트 226.4초
테스트 327.2초
테스트 426.9초
테스트 527.1초

 
어드민 페이지에서 해당 쿼리가 약 27초로 로딩 시간이 너무 길어 불편을 겪고 있습니다.
 
원인 분석 :

인덱스 (order_date) 경우, 범위가 약 8%(=약 70만건)로 많은 양의 레코드를 읽고 정렬 수행

인덱스 (sum_price) 경우, ORDER BY에서 LIMIT 만족 시 즉시 결과 반환 예상

 
MySQL의 innoDB 인덱스는 구조상 (sum_price) 인덱스에 (sum_price, id)로 PK 값이 마지막에 자동으로 삽입됩니다.
그러나, 정렬 방향 (sum_price DESC, id ASC)인덱스 정렬 방향(sum_price ASC, id ASC)가 불일치하여 풀스캔 및 정렬이 발생됩니다. 역방향 스캔 방향도 일치하지 않습니다.
 
해결 방안 1안 : 
ORDER BY sum_price DESC, id DESC로 쿼리 변경
해당 순서에 맞게 정렬할 경우 인덱스 정렬 방향과 일치하여 LIMIT 10,10으로 즉시 결과가 반환되어 지연 발생 없음
 
해결 방안 2안 : 
정렬 변경 없이 (sum_price ASC, id DESC) 인덱스 추가
해당 인덱스를 추가할 경우 기존 ORDER BY 순서와 인덱스 정렬 방향이 일치하여 지연 발생 없음
 
해결 방안 1-2에 대한 테스트 : 

테스트 10.001초
테스트 20.001초
테스트 30.001초
테스트 40.001초
테스트 50.001초

 
결론 : 
id 정렬 순서가 상관 없으면 스키마 변경 없이 쿼리 변경만으로 가능한 1안(id DESC)
비즈니스 로직 상 정렬 순서 변경이 어려운 경우 2안(인덱스 추가)를 선택하겠습니다.