테마
「상품 유형별 연 매출」은 한 해 주문의 주문상세를 상품 유형(4종)으로 묶는다. 원래 힌트는 LEADING(o d m) USE_HASH(d m)이었다.
조민우가 06화의 "작은 쪽을 build로"를 읽고, 상품 100행이 build가 되도록 M_ITM을 LEADING 맨 앞으로 옮겼다. 그 뒤로 0.1초이던 리포트가 10초 가까이 걸리고 TEMP 경보가 울린다. Buffers는 거의 그대로라서 조민우는 원인을 못 찾고 있다. 아래는 2024년으로 조회한 실행계획이다.
T_ORD: 100,000행 · 896블록 · PK_T_ORD (ORD_SEQ) · 2024년 주문 50,000건T_ORD_DET: 200,000행 · 896블록 · PK_T_ORD_DET (ORD_SEQ, ORD_DET_NO) · 2024년 주문의 상세 100,000줄M_ITM: 100행 · 5블록 · PK_M_ITM (ITM_ID) · ITM_TP 4종 (TP_A ~ TP_D, 25개씩)pga_aggregate_target 512M · AUTOSELECT /*+ LEADING(m o d) USE_HASH(o d) */
m.ITM_TP, COUNT(*) AS det_cnt, SUM(d.ORD_QTY * d.UNT_PRC) AS sale_amt
FROM T_ORD o, T_ORD_DET d, M_ITM m
WHERE o.ORD_DT >= TO_DATE(:v_yyyy || '0101', 'YYYYMMDD')
AND o.ORD_DT < ADD_MONTHS(TO_DATE(:v_yyyy || '0101', 'YYYYMMDD'), 12)
AND d.ORD_SEQ = o.ORD_SEQ
AND m.ITM_ID = d.ITM_ID
GROUP BY m.ITM_TP
---------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem | Used-Tmp|
---------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 4 |00:00:09.71 | 1797 | | | | |
| 1 | HASH GROUP BY | | 1 | 4 | 4 |00:00:09.71 | 1797 | 1116K| 1116K| 655K (0)| |
|* 2 | HASH JOIN | | 1 | 100K| 100K|00:00:09.68 | 1797 | 236M| 14M| 98M (1)| 187M|
| 3 | MERGE JOIN CARTESIAN| | 1 | 5000K| 5000K|00:00:01.32 | 901 | | | | |
| 4 | TABLE ACCESS FULL | M_ITM | 1 | 100 | 100 |00:00:00.01 | 5 | | | | |
| 5 | BUFFER SORT | | 100 | 50000 | 5000K|00:00:00.71 | 896 | 2316K| 743K| 2058K (0)| |
|* 6 | TABLE ACCESS FULL | T_ORD | 1 | 50000 | 50000 |00:00:00.02 | 896 | | | | |
| 7 | TABLE ACCESS FULL | T_ORD_DET | 1 | 200K| 200K|00:00:00.03 | 896 | | | | |
---------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("D"."ORD_SEQ"="O"."ORD_SEQ" AND "M"."ITM_ID"="D"."ITM_ID")
6 - filter(("O"."ORD_DT">=TO_DATE(:V_YYYY||'0101','YYYYMMDD') AND
"O"."ORD_DT"<ADD_MONTHS(TO_DATE(:V_YYYY||'0101','YYYYMMDD'),12)))
MERGE JOIN CARTESIAN이 왜 생겼는지, 그 5,000K 행이 어디서 나왔는지 설명하시오. Buffers는 거의 같은데 9.7초가 걸리는 이유를 메모리 열로 설명하시오.M_ITM을 build로 쓰도록 힌트를 고치시오. LEADING과 SWAP_JOIN_INPUTS가 각각 무엇을 정하는지 서술하시오.