Skip to content
튜닝 연습인덱스 스캔 효율과 테이블 액세스
ACC-003

재무팀이 1년치를 고르자 「기간 매출」 조회가 33만 블록을 읽는다

기초SELECT한빛유통78 / 700

상황 ​

정산 화면의 「기간 매출」 조회는 조건을 고친 뒤 인덱스를 탈 수 있게 되었다. 그러자 개발자가 "앞으로도 꼭 인덱스를 타게" 하겠다며 INDEX 힌트를 넣었다. 하루나 이틀 조회는 빨라졌다(하루 919블록). 연말에 재무팀이 1년치를 고르자 화면이 한참 돌아간다. 아래는 2024년 1년치(:v_from = '20240101', :v_to = '20241231')를 조회했을 때다.

테이블과 인덱스 ​

  • T_ORD_BIG: 1,000,000행 · 5,826블록 · ORD_DT 하루 913건(전부 자정) · 2024년 333,245건(33.3%)
  • 인덱스 IX_ORD_BIG_DT (ORD_DT): BLEVEL 2 · LEAF_BLOCKS 2,653 · CLUSTERING_FACTOR 1,000,000 · 통계 최신(교재 04화 실측)
  • 이 문제에는 커버링 인덱스 (ORD_DT, ORD_AMT)가 없다

원본 SQL ​

sql
SELECT /*+ INDEX(o IX_ORD_BIG_DT) */
       COUNT(*), SUM(o.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

실행계획 학습용 예시 · Buffers는 교재 04화 실측 ​

xplan
--------------------------------------------------------------------------------------------------------------
| Id  | Operation                             | Name          | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
--------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                      |               |      1 |        |      1 |00:00:00.36 |    334K|
|   1 |  SORT AGGREGATE                       |               |      1 |      1 |      1 |00:00:00.36 |    334K|
|*  2 |   FILTER                              |               |      1 |        |    333K|00:00:00.33 |    334K|
|   3 |    TABLE ACCESS BY INDEX ROWID BATCHED| T_ORD_BIG     |      1 |    334K|    333K|00:00:00.31 |    334K|
|*  4 |     INDEX RANGE SCAN                  | IX_ORD_BIG_DT |      1 |    334K|    333K|00:00:00.04 |     886 |
--------------------------------------------------------------------------------------------------------------

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

(0번 줄 Buffers 정확한 값 334,132 · 같은 조건 FULL 강제 5,826)

문제 ​

  1. Buffers 334,132가 어디서 나오는지 IX_ORD_BIG_DT의 BLEVEL, LEAF_BLOCKS, CLUSTERING_FACTOR로 분해하여 설명하시오. FULL이 5,826블록으로 끝나는 이유와 견주어 설명하시오.
  2. SQL을 고치시오. 이 테이블에서 이 인덱스가 FULL보다 싼 범위는 대략 며칠까지인지 구하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자