테마
한빛유통은 매월 1일 02:00에 주문 10만 건의 상태를 주문 이력 T_ORD_HIS에 스냅샷으로 남긴다. 이력 번호(HIS_SEQ)는 2016년에 만든 트리거 TRG_ORD_HIS_BI가 시퀀스로 채운다. 고객센터의 주문 상태 변경 화면도 T_ORD_HIS에 한 줄씩 넣는데, 이 화면은 HIS_SEQ 자리에 NULL을 넣는다(트리거가 채운다는 전제다).
스냅샷이 3.6초 걸린다. 오과장이 물었다. "같은 T_ORD 10만 건을 넣는 P1 적재는 0.4초인데 왜 아홉 배죠?"
T_ORD: 100,000행 · 896블록T_ORD_HIS 주문 이력(이 문제용): HIS_SEQ NUMBER NOT NULL · ORD_SEQ · ORD_ST · HIS_DT · HIS_TP('SNAP' 월초 스냅샷, 'CHG' 상태 변경) · PK_T_ORD_HIS (HIS_SEQ) · 지금 2,412,000행SQ_ORD_HIS: CACHE 20(기본값) · 이력 번호는 겹치지만 않으면 되고, 결번은 상관없다INSERT INTO T_ORD_HIS VALUES (NULL, :ord_seq, :st, SYSDATE, 'CHG') · 하루 약 600번 · 화면 소스는 이번에 고치지 않는다-- 2016년 트리거 — 이력 번호를 시퀀스로 채운다
CREATE OR REPLACE TRIGGER TRG_ORD_HIS_BI
BEFORE INSERT ON T_ORD_HIS
FOR EACH ROW
BEGIN
SELECT SQ_ORD_HIS.NEXTVAL INTO :NEW.HIS_SEQ FROM dual;
END;
/
-- 월초 주문 스냅샷 (매월 1일 02:00)
INSERT INTO T_ORD_HIS (ORD_SEQ, ORD_ST, HIS_DT, HIS_TP)
SELECT ORD_SEQ, ORD_ST, TRUNC(SYSDATE), 'SNAP'
FROM T_ORD;
COMMIT;
[세션 통계 — 월초 스냅샷 10만 건]
경과 시간 3.62 초 · CPU 3.31 초
recursive calls 105,061
execute count 105,014
session logical reads 341,207
redo size 38.9 MB
[TKPROF]
INSERT INTO T_ORD_HIS (ORD_SEQ, ORD_ST, HIS_DT, HIS_TP) SELECT ORD_SEQ, ORD_ST, TRUNC(SYSDATE), 'SNAP' FROM T_ORD (dep=0)
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Execute 1 0.95 1.02 0 904 314377 100000
SELECT SQ_ORD_HIS.NEXTVAL FROM DUAL (dep=1 · 트리거 안)
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Execute 100000 1.44 1.52 0 0 0 0
Fetch 100000 0.38 0.41 0 0 0 100000
update seq$ set increment$=:2,minvalue=:3,maxvalue=:4,cycle#=:5,order$=:6,cache=:7,highwater=:8,... where obj#=:1 (dep=2)
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Execute 5000 0.22 0.24 0 5000 10213 5000
[비교 — P1 적재 (T_ORD → T_ORD_STLM · 트리거 없음)] 경과 0.41 초 · recursive calls 31
HIS_SEQ에 NULL을 넣는다는 점을 어떻게 처리했는지도 쓰시오.