Skip to content
튜닝 연습소트 튜닝과 페이징
SORT-032

날짜 칸을 글자로 바꿔 준 다음 날부터 연간 주문 금액 내려받기가 세 배 느려졌다

기초SELECT한빛유통337 / 700

상황 ​

재무팀과 영업기획팀의 분석 시트 20개는 업무 시간 동안 매시 정각에 「2024년 주문 금액 원자료」(주문일과 금액, 주문일순)를 자동으로 내려받는다. 하루 약 200번이다. 지난주 재무팀이 "엑셀이 날짜를 제멋대로 바꾸니 주문일을 'YYYY-MM-DD' 글자로 달라"고 했고, 개발자는 시트의 칸 이름이 바뀌지 않도록 별칭을 그대로 ORD_DT로 둔 채 컬럼을 TO_CHAR로 감쌌다. 그다음 날부터 내려받기가 0.12초에서 0.38초로 늘었다. DBA는 인덱스만 읽던 SQL의 실행계획에 정렬 줄과 10MB 작업 공간이 새로 생긴 것을 찾았다.

테이블과 인덱스 ​

  • T_ORD_BIG: 1,000,000행 · 5,826블록 · ORD_DT DATE(전부 자정, 2022-01-01 ~ 2024-12-31) · 2024년 주문 333,968행
  • 인덱스 IX_ORD_BIG_DT_AMT (ORD_DT, ORD_AMT)(02화에서 만든 커버링 인덱스): BLEVEL 2 · 리프 약 3,320블록(한 블록에 약 300개) · 2024년 범위는 리프 약 1,110블록
  • 내려받기 도구는 한 번에 5,000행씩 가져온다(Fetch 약 67번). 통계는 최신이다.

원본 SQL ​

sql
SELECT TO_CHAR(o.ORD_DT, 'YYYY-MM-DD') AS ORD_DT,
       o.ORD_AMT
  FROM T_ORD_BIG o
 WHERE o.ORD_DT >= DATE '2024-01-01'
   AND o.ORD_DT <  DATE '2025-01-01'
 ORDER BY ORD_DT

실행계획 학습용 예시 ​

xplan
[지난주까지 : SELECT o.ORD_DT, o.ORD_AMT … ORDER BY ORD_DT]
------------------------------------------------------------------------------------------------------------------------
| Id  | Operation          | Name              | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |                   |      1 |        |    333K|00:00:00.12 |    1179 |       |       |          |
|*  1 |  INDEX RANGE SCAN  | IX_ORD_BIG_DT_AMT |      1 |    334K|    333K|00:00:00.12 |    1179 |       |       |          |
------------------------------------------------------------------------------------------------------------------------

[지금 : TO_CHAR(o.ORD_DT, 'YYYY-MM-DD') AS ORD_DT … ORDER BY ORD_DT]
------------------------------------------------------------------------------------------------------------------------
| Id  | Operation          | Name              | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |                   |      1 |        |    333K|00:00:00.38 |    1112 |       |       |          |
|   1 |  SORT ORDER BY     |                   |      1 |    334K|    333K|00:00:00.38 |    1112 |    12M|  1393K|   10M (0)|
|*  2 |   INDEX RANGE SCAN | IX_ORD_BIG_DT_AMT |      1 |    334K|    333K|00:00:00.07 |    1112 |       |       |          |
------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("O"."ORD_DT">=TO_DATE(' 2024-01-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND
              "O"."ORD_DT"<TO_DATE(' 2025-01-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))

문제 ​

  1. 같은 인덱스를 같은 범위만큼 읽는데 지난주에는 없던 1번 줄 SORT ORDER BY가 생긴 까닭을 ORDER BY ORD_DT가 무엇을 가리키는지로 설명하시오.
  2. 재무팀이 원한 날짜 모양과 칸 이름을 지키면서 정렬 줄이 다시 사라지도록 SQL을 고치고, 고친 SQL의 결과 순서가 지금과 같다고 말할 수 있는 근거를 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자