테마
상담 화면 맨 위의 「VIP 최근 30일」 칸은 A 등급 고객 20명마다 최근 30일 주문 건수, 금액, 취소 건수를 보여 준다. 30일 동안 주문이 없는 VIP도 0으로 보여야 해서 아우터 조인으로 썼다. 상담 화면이 열릴 때마다 호출되어 하루 3천 번쯤 돈다.
힌트 옆에는 -- 외부 조인은 해시로 (등급별 주문 상태 리포트 튜닝 때 결론)이라는 주석이 있다. 아래는 2024-06-01 ~ 2024-06-30으로 조회한 실행계획이다.
M_CUS: 2,000행 · 30블록 · PK_M_CUS (CUS_ID) · A 등급 20명T_ORD_BIG: 1,000,000행 · 5,826블록 · 30일 주문 약 27,400건 · 고객 한 명은 한 달 평균 13.7건IX_ORD_BIG_CUS_DT (CUS_ID, ORD_DT, ORD_AMT): 영업팀 화면용으로 작년에 만들었다 · ORD_ST는 담지 않는다SELECT /*+ LEADING(c o) USE_HASH(o) */ -- 외부 조인은 해시로 (등급별 주문 상태 리포트 튜닝 때 결론)
c.CUS_ID, c.CUS_NM,
COUNT(o.ORD_SEQ) AS ord_cnt,
NVL(SUM(o.ORD_AMT), 0) AS ord_amt,
COUNT(CASE WHEN o.ORD_ST = 'CANCEL' THEN 1 END) AS cancel_cnt
FROM M_CUS c, T_ORD_BIG o
WHERE c.CUS_GD = 'A'
AND o.CUS_ID(+) = c.CUS_ID
AND o.ORD_DT(+) >= :v_from
AND o.ORD_DT(+) < :v_to
GROUP BY c.CUS_ID, c.CUS_NM
---------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Used-Mem |
---------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 20 |00:00:00.09 | 5856 | |
| 1 | HASH GROUP BY | | 1 | 20 | 20 |00:00:00.09 | 5856 | 1045K (0)|
|* 2 | HASH JOIN OUTER | | 1 | 274 | 275 |00:00:00.09 | 5856 | 1250K (0)|
|* 3 | TABLE ACCESS FULL| M_CUS | 1 | 20 | 20 |00:00:00.01 | 30 | |
|* 4 | TABLE ACCESS FULL| T_ORD_BIG | 1 | 27390 | 27403 |00:00:00.08 | 5826 | |
---------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("O"."CUS_ID"(+)="C"."CUS_ID")
3 - filter("C"."CUS_GD"='A')
4 - filter(("O"."ORD_DT">=:V_FROM AND "O"."ORD_DT"<:V_TO))