테마
월말 마감의 「취소 주문 전수 점검」은 취소 주문 전부를 고객별로 묶어 원장과 맞춘다. 마감 날에는 단계마다 돌아서 하루 30번쯤 실행된다. 소스에는 /*+ INDEX(o (ORD_ST)) */ 힌트와 함께 "상태 인덱스를 꼭 타게 (2019 강도현)"라는 주석이 있다.
지난주 DBA가 접두 중복 규칙(교재 04화 §6)에 따라 IX_ORD_BIG_ST (ORD_ST)를 지웠다. "(ORD_ST, ORD_DT)의 접두부라서 하던 일은 그 인덱스가 대신한다." 실행계획을 보니 점검 SQL도 남은 인덱스를 탄다. 그런데 이번 마감에서 한 번에 5,878블록이던 점검이 20,074블록이 됐다.
박팀장은 이렇게 주문했다. "인덱스를 되살릴지, 다른 길이 있는지, 정리 규칙은 어떻게 고칠지 숫자로 적어 와라."
T_ORD_BIG: 1,000,000행 · 5,826블록(블록당 약 172행) · ORD_SEQ 순으로 쌓였다 · ORD_DT 1,095일(하루 913건, 전부 자정)ORD_ST = 'CANCEL') 20,000건(2%): ORD_SEQ가 50의 배수인 주문이다 · 같은 날짜의 취소 주문은 ORD_SEQ가 10,950씩 떨어져 있다 · 취소 주문이 있는 고객은 40명IX_ORD_BIG_ST (ORD_ST): BLEVEL 2 · 리프 약 2,500블록 · CLUSTERING_FACTOR 17,478IX_ORD_BIG_ST_DT (ORD_ST, ORD_DT): 「취소 추이」 화면용(ACC-001의 처방) · BLEVEL 2 · 리프 약 3,610블록 · CLUSTERING_FACTOR 약 1,000,000IX_ORD_BIG_DT (ORD_DT) · 통계 최신 · ORD_ST에 히스토그램 · 주문은 운영에서 계속 INSERT된다(교재 04화 실측: 인덱스 하나에 5만 건 적재 redo 약 11.8MB)SELECT /*+ INDEX(o (ORD_ST)) */
o.CUS_ID, COUNT(*) AS cnl_cnt, SUM(o.ORD_AMT) AS cnl_amt
FROM T_ORD_BIG o
WHERE o.ORD_ST = 'CANCEL'
GROUP BY o.CUS_ID
[지난달 마감: IX_ORD_BIG_ST가 있을 때]
------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 40 |00:00:00.06 | 5878 |
| 1 | HASH GROUP BY | | 1 | 2000 | 40 |00:00:00.06 | 5878 |
| 2 | TABLE ACCESS BY INDEX ROWID BATCHED| T_ORD_BIG | 1 | 20000 | 20000 |00:00:00.05 | 5878 |
|* 3 | INDEX RANGE SCAN | IX_ORD_BIG_ST | 1 | 20000 | 20000 |00:00:00.01 | 52 |
------------------------------------------------------------------------------------------------------------------
3 - access("O"."ORD_ST"='CANCEL')
[이번 마감: IX_ORD_BIG_ST를 지운 뒤]
------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 40 |00:00:00.18 | 20074 |
| 1 | HASH GROUP BY | | 1 | 2000 | 40 |00:00:00.18 | 20074 |
| 2 | TABLE ACCESS BY INDEX ROWID BATCHED| T_ORD_BIG | 1 | 20000 | 20000 |00:00:00.17 | 20074 |
|* 3 | INDEX RANGE SCAN | IX_ORD_BIG_ST_DT | 1 | 20000 | 20000 |00:00:00.01 | 74 |
------------------------------------------------------------------------------------------------------------------
3 - access("O"."ORD_ST"='CANCEL')
[같은 조건 · FULL 강제] TABLE ACCESS FULL 5,826