테마
고객관리팀은 VIP(A 등급) 고객의 취소를 이탈 징후로 본다. 상황판 다섯 대가 「VIP 최근 취소 20건」을 1분마다 새로 고친다. 지금까지 VIP의 취소는 한 건도 없어서 화면은 늘 비어 있는데, AWR에서 이 SQL이 Buffer Gets 2위다. 정하은이 물었다. "지난번 취소 정산 점검처럼 컬럼 그룹을 만들어서 두 열의 관계를 알려 주면 되지 않을까요?" 박팀장은 고칠 방법을 둘 이상 비교해서 고르라고 했다.
T_ORD_BIG: 1,000,000행 · 5,826블록 · ORD_ST COMPLETE 900,000 · PENDING 80,000 · CANCEL 20,000(FREQUENCY 히스토그램, 정책서 1호) · 매주 일요일에 인덱스를 단 채 재적재한다IX_ORD_BIG_ST_DT (ORD_ST, ORD_DT): BLEVEL 2 · 리프 약 3,300 / IX_ORD_BIG_CUS_DT (CUS_ID, ORD_DT): BLEVEL 2 · 리프 약 3,400 · 행이 흩어져 있어 두 인덱스 모두 CF가 100만에 가깝다M_CUS: 2,000행 · 30블록 · PK_M_CUS (CUS_ID) · CUS_GD A 20 · B 180 · C 1,800(FREQUENCY 히스토그램) · 고객당 주문 500건SELECT *
FROM (SELECT o.ORD_SEQ, o.ORD_DT, o.ORD_AMT, c.CUS_ID, c.CUS_NM
FROM T_ORD_BIG o, M_CUS c
WHERE o.ORD_ST = 'CANCEL'
AND c.CUS_GD = 'A'
AND c.CUS_ID = o.CUS_ID
ORDER BY o.ORD_DT DESC)
WHERE ROWNUM <= 20
--------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
--------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 0 |00:00:00.12 | 40489 |
|* 1 | COUNT STOPKEY | | 1 | | 0 |00:00:00.12 | 40489 |
| 2 | VIEW | | 1 | 20 | 0 |00:00:00.12 | 40489 |
| 3 | NESTED LOOPS | | 1 | 20 | 0 |00:00:00.12 | 40489 |
| 4 | NESTED LOOPS | | 1 | 2000 | 20000 |00:00:00.07 | 20489 |
| 5 | TABLE ACCESS BY INDEX ROWID | T_ORD_BIG | 1 | 20000 | 20000 |00:00:00.05 | 20069 |
|* 6 | INDEX RANGE SCAN DESCENDING| IX_ORD_BIG_ST_DT | 1 | 2000 | 20000 |00:00:00.01 | 69 |
|* 7 | INDEX UNIQUE SCAN | PK_M_CUS | 20000 | 1 | 20000 |00:00:00.01 | 420 |
|* 8 | TABLE ACCESS BY INDEX ROWID | M_CUS | 20000 | 1 | 0 |00:00:00.04 | 20000 |
--------------------------------------------------------------------------------------------------------
1 - filter(ROWNUM<=20)
6 - access("O"."ORD_ST"='CANCEL')
7 - access("C"."CUS_ID"="O"."CUS_ID")
8 - filter("C"."CUS_GD"='A')
E-Rows를 손으로 계산해 설명하고, 그 계획이 실제로 취소 2만 건을 끝까지 읽은 이유를 쓰시오.