테마
매월 1일 새벽 정산 마감 배치의 한 단계는 지난달 고객별 주문 건수, 주문 금액, 마지막 주문 일시를 고객 월 실적 테이블에 넣는다. 강도현이 남긴 인수인계 메모에는 "이 단계 0.7초, 고객 수가 늘면 같이 늘어남"이라고 적혀 있다. 오과장은 내년에 제휴사 고객을 받아 고객 수가 열 배로 는다며 미리 봐 달라고 했다.
M_CUS: 2,000행 · 30블록 · PK_M_CUS (CUS_ID)T_ORD: 100,000행 · 896블록 · 고객마다 50건(2,000행 간격으로 흩어져 있다) · 2024년 6월 4,110건(고객마다 2 ~ 3건) · PK_T_ORD (ORD_SEQ) · IX_ORD_CUS (CUS_ID)T_CUS_MON 고객 월 실적: 이 배치가 채우는 집계 테이블(BASE_YM, CUS_ID, ORD_CNT, ORD_AMT, LAST_ORD_DT) · 인덱스 없음_optimizer_unnest_scalar_sq = FALSE를 시스템 수준에 걸어 두었다(스칼라 서브쿼리 Unnesting을 하지 않는다)INSERT INTO T_CUS_MON (BASE_YM, CUS_ID, ORD_CNT, ORD_AMT, LAST_ORD_DT)
SELECT '202406', c.CUS_ID,
(SELECT COUNT(*)
FROM T_ORD o
WHERE o.CUS_ID = c.CUS_ID
AND o.ORD_DT >= DATE '2024-06-01' AND o.ORD_DT < DATE '2024-07-01'),
(SELECT NVL(SUM(o.ORD_AMT), 0)
FROM T_ORD o
WHERE o.CUS_ID = c.CUS_ID
AND o.ORD_DT >= DATE '2024-06-01' AND o.ORD_DT < DATE '2024-07-01'),
(SELECT MAX(o.ORD_DT)
FROM T_ORD o
WHERE o.CUS_ID = c.CUS_ID
AND o.ORD_DT >= DATE '2024-06-01' AND o.ORD_DT < DATE '2024-07-01')
FROM M_CUS c
----------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
----------------------------------------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 1 | | 0 |00:00:00.71 | 316K|
| 1 | LOAD TABLE CONVENTIONAL | T_CUS_MON | 1 | | 0 |00:00:00.71 | 316K|
| 2 | SORT AGGREGATE | | 2000 | 1 | 2000 |00:00:00.22 | 104K|
|* 3 | TABLE ACCESS BY INDEX ROWID BATCHED| T_ORD | 2000 | 2 | 4110 |00:00:00.21 | 104K|
|* 4 | INDEX RANGE SCAN | IX_ORD_CUS | 2000 | 50 | 100K|00:00:00.03 | 4612 |
| 5 | SORT AGGREGATE | | 2000 | 1 | 2000 |00:00:00.22 | 104K|
|* 6 | TABLE ACCESS BY INDEX ROWID BATCHED| T_ORD | 2000 | 2 | 4110 |00:00:00.21 | 104K|
|* 7 | INDEX RANGE SCAN | IX_ORD_CUS | 2000 | 50 | 100K|00:00:00.03 | 4612 |
| 8 | SORT AGGREGATE | | 2000 | 1 | 2000 |00:00:00.22 | 104K|
|* 9 | TABLE ACCESS BY INDEX ROWID BATCHED| T_ORD | 2000 | 2 | 4110 |00:00:00.21 | 104K|
|* 10 | INDEX RANGE SCAN | IX_ORD_CUS | 2000 | 50 | 100K|00:00:00.03 | 4612 |
| 11 | TABLE ACCESS FULL | M_CUS | 1 | 2000 | 2000 |00:00:00.01 | 30 |
----------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter(("O"."ORD_DT">=TO_DATE(' 2024-06-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')))
4 - access("O"."CUS_ID"=:B1)
(6 · 7 · 9 · 10 도 같은 모양)
(DBMS_XPLAN 이 줄여 쓴 값 — 104K = 104,612 · 316K = 315,962)
_optimizer_unnest_scalar_sq를 기본값으로 되돌리는 안과 SQL을 고치는 안을 비교하시오.