테마
고객관리팀의 「전담 상담 고객 실적」 리포트는 A와 B 등급 고객 200명의 상담 건수와 분기 주문 실적을 고객마다 한 줄씩 보여 준다. 팀장 회의 전에 하루 수십 번 돌린다. 분기는 화면이 리터럴로 넣는다(아래는 2024년 2분기). 정하은이 계획을 보고 물었다. "고객 200명의 주문만 보면 되는데 왜 주문 인덱스를 통째로 읽죠?" 이 리포트 SQL은 다른 팀도 같이 쓰고 있어서 이번에는 고치지 않기로 했다.
T_CS_CALL 전담 상담 이력(이 문제용): 36,000행 · 260블록 · CALL_SEQ · CALL_DT · CUS_ID · AGT_ID(전담 상담원) · RGN_ID(고객 지역) · A와 B 등급 고객 200명의 3년치 상담만 쌓인다(CUS_ID, AGT_ID, RGN_ID) 조합은 고객 수와 같은 200개다.T_CS_CALL 통계: 최신 · NUM_DISTINCT는 CUS_ID 200 · AGT_ID 12 · RGN_ID 8 · 히스토그램 없음 · 확장 통계 없음T_ORD_BIG: 1,000,000행 · 5,826블록 · 고객 2,000명 × 500건 · ORD_DT NDV 1,095(2022-01-01 ~ 2024-12-30) · 2024년 4 ~ 6월 주문 83,083건(고객 200명의 몫은 8,308건)IX_ORD_BIG_CUS_DT_AMT (CUS_ID, ORD_DT, ORD_AMT): BLEVEL 2 · 리프 3,950 · 이 SQL이 T_ORD_BIG에서 쓰는 열을 모두 담는다SELECT v.CUS_ID, v.AGT_ID, v.RGN_ID, v.call_cnt,
COUNT(*) AS ord_cnt, SUM(o.ORD_AMT) AS ord_amt
FROM (SELECT CUS_ID, AGT_ID, RGN_ID, COUNT(*) AS call_cnt
FROM T_CS_CALL
GROUP BY CUS_ID, AGT_ID, RGN_ID) v,
T_ORD_BIG o
WHERE o.CUS_ID = v.CUS_ID
AND o.ORD_DT >= DATE '2024-04-01'
AND o.ORD_DT < DATE '2024-07-01'
GROUP BY v.CUS_ID, v.AGT_ID, v.RGN_ID, v.call_cnt
Plan hash value: 3318260471
-------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Used-Mem |
-------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 200 |00:00:00.09 | 4231 | |
| 1 | HASH GROUP BY | | 1 | 19200 | 200 |00:00:00.09 | 4231 | 1394K (0)|
|* 2 | HASH JOIN | | 1 | 807K| 8308 |00:00:00.08 | 4231 | 2210K (0)|
| 3 | VIEW | | 1 | 19200 | 200 |00:00:00.01 | 260 | |
| 4 | HASH GROUP BY | | 1 | 19200 | 200 |00:00:00.01 | 260 | 1188K (0)|
| 5 | TABLE ACCESS FULL | T_CS_CALL | 1 | 36000 | 36000 |00:00:00.01 | 260 | |
|* 6 | INDEX FAST FULL SCAN | IX_ORD_BIG_CUS_DT_AMT | 1 | 84094 | 83083 |00:00:00.05 | 3971 | |
-------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("O"."CUS_ID"="V"."CUS_ID")
6 - filter(("O"."ORD_DT">=TO_DATE(' 2024-04-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND
"O"."ORD_DT"<TO_DATE(' 2024-07-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss')))
E-Rows 19,200이 어디서 나온 숫자인지 계산하고, 그 숫자 때문에 2번 줄에서 어떤 조인 방법을 골랐는지 설명하시오.