테마
버거원 본사는 매달 초 지난달 주문상품을 DW 이관용 스테이징(DW_ORD_ITEM_M)으로 옮긴다. 지금 배치는 주문상품을 한 건씩 읽어 상품명과 상품 유형을 찾아 붙인 뒤 한 건씩 넣는데, 12월분에 1.6초가 걸렸다.
개발자가 INSERT … SELECT 한 문장으로 바꾸자 0.2초로 줄었다. 그런데 DW 쪽 건수 대조에서 1,206건이 모자랐다. 에러는 하나도 없었다.
ORD_ITEM: 2,472,717행 · 55,265블록 · ORD_ITEM_X01 (ORD_DT, ORD_HMS) · 2013년 12월분 106,342행ITEM: 92행 · 5블록 · PK ITEM_ID. 2013년 11월 단종 정리 때 상품 3개를 지웠다(지우기 전 95개). 그 3개가 일부 매장 POS에 남아 12월에도 1,206행이 팔렸다.DW_ORD_ITEM_M(이 문제용 테이블): 한 달 치만 담는 스테이징이다. 배치를 시작할 때 비운다(TRUNCATE). 인덱스는 없고, DW가 배치가 끝난 뒤에 읽는다.(단종), 유형 ZZ로 받는다"이다. DB는 NOARCHIVELOG다.-- 지금 배치 (1.6초)
DECLARE
v_nm ITEM.ITEM_NM%TYPE;
v_tp ITEM.ITEM_TYPE_CD%TYPE;
BEGIN
EXECUTE IMMEDIATE 'TRUNCATE TABLE DW_ORD_ITEM_M';
FOR r IN (SELECT ORD_NO, ITEM_ID, ORD_ITEM_QTY, ORD_DT
FROM ORD_ITEM
WHERE ORD_DT BETWEEN '20131201' AND '20131231') LOOP
BEGIN
SELECT ITEM_NM, ITEM_TYPE_CD INTO v_nm, v_tp
FROM ITEM WHERE ITEM_ID = r.ITEM_ID;
EXCEPTION
WHEN NO_DATA_FOUND THEN v_nm := '(단종)'; v_tp := 'ZZ';
END;
INSERT INTO DW_ORD_ITEM_M (ORD_NO, ITEM_ID, ITEM_NM, ITEM_TYPE_CD, ORD_ITEM_QTY, ORD_DT)
VALUES (r.ORD_NO, r.ITEM_ID, v_nm, v_tp, r.ORD_ITEM_QTY, r.ORD_DT);
END LOOP;
COMMIT;
END;
-- 개발자가 바꾼 판 (0.2초 · 1,206건 모자람)
INSERT INTO DW_ORD_ITEM_M (ORD_NO, ITEM_ID, ITEM_NM, ITEM_TYPE_CD, ORD_ITEM_QTY, ORD_DT)
SELECT i.ORD_NO, i.ITEM_ID, t.ITEM_NM, t.ITEM_TYPE_CD, i.ORD_ITEM_QTY, i.ORD_DT
FROM ORD_ITEM i, ITEM t
WHERE t.ITEM_ID = i.ITEM_ID
AND i.ORD_DT BETWEEN '20131201' AND '20131231';
[지금 배치 — 세션 통계]
경과 시간 1.58 ~ 1.66 초
recursive calls 213,104
execute count 212,698 (상품 SELECT INTO 106,342 · INSERT 106,342)
session logical reads 약 330,400
redo size 약 30.2 MB
적재 행 106,342
[바꾼 판 — DISPLAY_CURSOR (ALLSTATS LAST)]
----------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Used-Mem |
----------------------------------------------------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 1 | | 0 |00:00:00.21 | 4930 | |
| 1 | LOAD TABLE CONVENTIONAL | DW_ORD_ITEM_M | 1 | | 0 |00:00:00.21 | 4930 | |
|* 2 | HASH JOIN | | 1 | 106K| 105K|00:00:00.06 | 2688 | 1376K (0)|
| 3 | TABLE ACCESS FULL | ITEM | 1 | 92 | 92 |00:00:00.01 | 5 | |
| 4 | TABLE ACCESS BY INDEX ROWID BATCHED | ORD_ITEM | 1 | 106K| 106K|00:00:00.03 | 2683 | |
|* 5 | INDEX RANGE SCAN | ORD_ITEM_X01 | 1 | 106K| 106K|00:00:00.01 | 381 | |
----------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("T"."ITEM_ID"="I"."ITEM_ID")
5 - access("I"."ORD_DT">='20131201' AND "I"."ORD_DT"<='20131231')
[DW 건수 대조] 원천 ORD_ITEM 12월 106,342 · 스테이징 105,136 · 차이 1,206 (지운 상품 3개)