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

힌트까지 붙였는데 건수 한 줄이 테이블을 다 읽는다

기초SELECT한빛유통81 / 700

상황 ​

월말 마감 대사 작업이다. 마감 담당 오과장의 검증 스크립트는 단계가 끝날 때마다 T_ORD_BIG의 전체 건수를 원장과 맞춰 본다. 단계마다 돌고, 재실행하고, 사람이 손으로 한 번 더 돌리다 보니 마감 하루에 이 문장이 200번 넘게 실행된다. 조민우는 "ORD_DT 인덱스가 있으니 인덱스만 세면 된다" 하고 INDEX_FFS 힌트를 붙였다. 그런데 실행계획은 그대로다.

테이블과 인덱스 ​

  • T_ORD_BIG: 1,000,000행 · 5,826블록 · PK 없음
  • 컬럼 선언: ORD_SEQ NUMBER NOT NULL · CUS_ID VARCHAR2(40) NOT NULL · ORD_DT DATE (NULL 허용) · ORD_ST · ORD_AMT
  • 인덱스는 IX_ORD_BIG_DT (ORD_DT) 하나뿐이다(LEAF 2,653 · 통계 최신)
  • ORD_DT의 실제 NULL은 0건이다(NUM_NULLS = 0). 적재 프로그램은 주문일을 늘 채운다

원본 SQL ​

sql
SELECT /*+ INDEX_FFS(o IX_ORD_BIG_DT) */ COUNT(*)
  FROM T_ORD_BIG o

실행계획 학습용 예시 ​

xplan
----------------------------------------------------------------------------------------
| Id  | Operation          | Name      | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |           |      1 |        |      1 |00:00:00.04 |    5826 |
|   1 |  SORT AGGREGATE    |           |      1 |      1 |      1 |00:00:00.04 |    5826 |
|   2 |   TABLE ACCESS FULL| T_ORD_BIG |      1 |   1000K|   1000K|00:00:00.04 |    5826 |
----------------------------------------------------------------------------------------

Hint Report (identified by operation id / Query Block Name / Object Alias):
Total hints for statement: 1 (U - Unused (1))
---------------------------------------------------------------------------

   2 -  SEL$1 / "O"@"SEL$1"
         U -  INDEX_FFS(o IX_ORD_BIG_DT)

문제 ​

  1. 인덱스가 있고 힌트까지 붙였는데도 TABLE ACCESS FULL로 처리되는 이유를, B-tree 인덱스에 무엇이 들어 있고 무엇이 빠지는지를 근거로 설명하시오.
  2. 결과(전체 건수)의 뜻을 바꾸지 않고 인덱스만 읽어 건수를 세도록 고치시오. 그 조치를 하기 전에 무엇을 확인해야 하는지, 그 조치가 다른 프로그램에 어떤 영향을 주는지도 설명하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자