테마
본사 레거시 유통의 「월 상품 실적」 배치는 매달 1일 03:00에 돈다. 매장 POS가 보낸 지난달 판매상품 파일을 작업 테이블 W_SLE_MON에 올리고(sqlldr 일반 경로), 매장 · 상품별로 묶어 CF19에 MERGE한 뒤, 저장 공간을 돌려주려고 작업 테이블을 비운다.
DBA의 야간 잡 PKG_STATS.NIGHTLY(매일 23:40)는 목록 표 STATS_TARGET의 테이블을 하나씩 GATHER_TABLE_STATS로 모은다. W_SLE_MON은 배치를 만들 때 목록에 넣었다. 선배가 물었다. "그 잡이 이 테이블을 모을 때 테이블에 뭐가 들어 있었을까?"
W_SLE_MON 월 판매상품 작업 테이블(이 문제용): SLE_NO · ITM_NO · SLE_QTY · SLE_UPRC · 채웠을 때 약 45,900행(6월분 45,912행) · 342블록 · 인덱스 없음W_SLE_MON 통계: NUM_ROWS 0 · BLOCKS 0 · 마지막 수집 6월 30일 23:40(야간 잡 · 달마다 채운 지 몇 분 만에 비우므로 야간 잡은 늘 빈 테이블을 본다)CF10 판매: 500,000행 · 4,583블록 · CF10_PK (SLE_NO) · 6월 판매 20,953건 · 통계 최신CF19 상품 월 실적(이 문제용): 매장 6 × 상품 약 109 × 월 · 달마다 약 654행 · PK (SHP_NO, ITM_NO, SLE_YM) · 28블록GATHER_TABLE_STATS를 부른다. 달마다 크기는 45,000행 안팎으로 비슷하다.-- 매달 1일 03:00 · 월 상품 실적
-- ① sqlldr 로 W_SLE_MON 에 지난달 판매상품 파일을 올린다 (일반 경로 · 약 45,900행)
-- ② MERGE
MERGE INTO CF19 t
USING (SELECT a.SHP_NO, w.ITM_NO,
SUM(w.SLE_QTY) AS qty, SUM(w.SLE_QTY * w.SLE_UPRC) AS amt
FROM W_SLE_MON w, CF10 a
WHERE a.SLE_NO = w.SLE_NO
GROUP BY a.SHP_NO, w.ITM_NO) s
ON (t.SHP_NO = s.SHP_NO AND t.ITM_NO = s.ITM_NO AND t.SLE_YM = :ym)
WHEN MATCHED THEN
UPDATE SET t.SLE_QTY = s.qty, t.SLE_AMT = s.amt
WHEN NOT MATCHED THEN
INSERT (SHP_NO, ITM_NO, SLE_YM, SLE_QTY, SLE_AMT)
VALUES (s.SHP_NO, s.ITM_NO, :ym, s.qty, s.amt);
COMMIT;
-- ③ 저장 공간을 돌려준다
TRUNCATE TABLE W_SLE_MON;
[7월 1일 03:00 · ② MERGE]
-------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
-------------------------------------------------------------------------------------------------------------------
| 0 | MERGE STATEMENT | | 1 | | 0 |00:00:01.86 | 186K | 312 |
| 1 | MERGE | CF19 | 1 | | 0 |00:00:01.86 | 186K | 312 |
| 2 | VIEW | | 1 | | 654 |00:00:01.84 | 184K | 312 |
|* 3 | HASH JOIN OUTER | | 1 | 1 | 654 |00:00:01.84 | 184K | 312 |
| 4 | VIEW | | 1 | 1 | 654 |00:00:01.83 | 184K | 312 |
| 5 | HASH GROUP BY | | 1 | 1 | 654 |00:00:01.83 | 184K | 312 |
| 6 | NESTED LOOPS | | 1 | 1 | 45912 |00:00:01.79 | 184K | 312 |
| 7 | NESTED LOOPS | | 1 | 1 | 45912 |00:00:00.93 | 138K | 118 |
| 8 | TABLE ACCESS FULL | W_SLE_MON | 1 | 1 | 45912 |00:00:00.01 | 342 | 0 |
|* 9 | INDEX UNIQUE SCAN | CF10_PK | 45912 | 1 | 45912 |00:00:00.88 | 138K | 118 |
| 10 | TABLE ACCESS BY INDEX ROWID | CF10 | 45912 | 1 | 45912 |00:00:00.81 | 45912 | 194 |
| 11 | TABLE ACCESS FULL | CF19 | 1 | 654 | 3924 |00:00:00.01 | 28 | 0 |
-------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("T"."SLE_YM"=:YM AND "T"."ITM_NO"="S"."ITM_NO" AND "T"."SHP_NO"="S"."SHP_NO")
9 - access("A"."SLE_NO"="W"."SLE_NO")
[USER_TAB_STATISTICS — W_SLE_MON]
NUM_ROWS BLOCKS LAST_ANALYZED STALE_STATS STATTYPE_LOCKED
0 0 06-30 23:40 NO -