Skip to content
튜닝 연습인덱스 사용 조건
IDX-064

인덱스 정리 뒤로 「기간 매출」이 인덱스만 읽는데도 91블록에서 4천 블록으로 늘었다

기초SELECT한빛유통64 / 700

상황 ​

지난주 DBA가 T_ORD_BIG의 인덱스를 정리했다. 정리 기준은 이렇게 적혀 있다. "컬럼이 모두 다른 인덱스에 들어 있는 인덱스는 중복이다. (ORD_DT, ORD_AMT)의 두 컬럼은 (CUS_ID, ORD_DT, ORD_AMT)에 다 있으므로 지운다." 그 뒤로 정산 화면의 「기간 매출」(교재 02화에서 고친 그 조회, 하루 수천 번)이 느려졌다. 조민우는 "실행계획에 아직 인덱스 이름이 나오니 인덱스는 타고 있다"고 한다. 아래는 2024년 6월을 넘겼을 때다.

테이블과 인덱스 ​

  • T_ORD_BIG: 1,000,000행 · 5,826블록 · ORD_DT 전부 자정 · 2024년 6월 27,390건 · CUS_ID 2,000명
  • 남은 인덱스 IX_ORD_BIG_CUS_DT_AMT (CUS_ID, ORD_DT, ORD_AMT): ACC-043에서 「고객별 주문 원장」용으로 만든 인덱스 · BLEVEL 2 · 리프 약 4,100블록 · 통계 최신
  • 지운 인덱스 IX_ORD_BIG_DT_AMT (ORD_DT, ORD_AMT): 리프 3,206블록(교재 04화 실측) · 같은 조회를 91블록에 끝냈다(교재 02화 실측)
  • 다른 인덱스는 없다 · 주문은 운영에서 계속 INSERT된다(인덱스 하나에 5만 건당 redo 약 12MB, 교재 14화)

원본 SQL ​

sql
SELECT COUNT(*) AS ord_cnt, SUM(o.ORD_AMT) AS ord_amt
  FROM T_ORD_BIG o
 WHERE o.ORD_DT >= TO_DATE(:v_from, 'YYYYMMDD')
   AND o.ORD_DT <  TO_DATE(:v_to, 'YYYYMMDD') + 1

실행계획 학습용 예시 ​

xplan
---------------------------------------------------------------------------------------------------------
| Id  | Operation              | Name                  | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
---------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |                       |      1 |        |      1 |00:00:00.09 |    4126 |
|   1 |  SORT AGGREGATE        |                       |      1 |      1 |      1 |00:00:00.09 |    4126 |
|*  2 |   FILTER               |                       |      1 |        |  27390 |00:00:00.09 |    4126 |
|*  3 |    INDEX FAST FULL SCAN| IX_ORD_BIG_CUS_DT_AMT |      1 |  27390 |  27390 |00:00:00.08 |    4126 |
---------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter(TO_DATE(:V_TO,'YYYYMMDD')+1>TO_DATE(:V_FROM,'YYYYMMDD'))
   3 - filter(("O"."ORD_DT">=TO_DATE(:V_FROM,'YYYYMMDD') AND "O"."ORD_DT"<TO_DATE(:V_TO,'YYYYMMDD')+1))

문제 ​

  1. 실행계획에 인덱스 이름이 나오는데도 4,126블록을 읽는 이유를 INDEX FAST FULL SCAN과 인덱스의 선두 컬럼으로 설명하시오. 옵티마이저가 SKIP SCAN을 고르지 않은 이유도 설명하시오.
  2. DBA의 정리 기준이 무엇을 놓쳤는지 설명하고, 「기간 매출」을 되살리는 DDL과 고쳐 쓴 정리 기준을 제시하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자