테마
본사 레거시 유통의 판매상품 CF11에는 2016년에 만든 검증 트리거가 있다. 판매 번호와 상품 번호가 실제로 있는지, 수량이 양수인지 행마다 확인한다. 이번 주 매장 POS 서버를 바꾸면서 11월 판매상품 45,370행을 다시 받아 넣었는데(기존 11월분은 지웠다), 이 INSERT 한 문장에서 SQL이 9만 번 넘게 실행됐다.
같은 주 감사 점검에서는 상품 마스터에 없는 상품 번호를 가진 판매상품 2행이 나왔다. 개발팀: "트리거가 다 막는데 어떻게 들어갔는지 모르겠어요."
CF10 판매: 500,000행 · 4,583블록 · CF10_PK (SLE_NO) · 11월 20,712건CF11 판매상품: 1,096,708행 · 8,204블록 · CF11_PK (SLE_NO, ITM_NO) · 이 문제에서는 FK가 없고 트리거 TRG_CF11_CHK가 대신한다. ITM_NO가 맨 앞인 인덱스는 없다.CF01 상품: 109행 · 5블록 · PK ITM_NO · 분기마다 「미출시 상품 정리」 배치가 판매 이력이 없는 상품을 지운다.CF11_RCV 수신 테이블: 11월 판매상품 45,370행. 반품은 다른 테이블이라 SLE_QTY는 언제나 양수여야 한다.-- 2016년부터 있는 검증 트리거
CREATE OR REPLACE TRIGGER TRG_CF11_CHK
BEFORE INSERT OR UPDATE ON CF11
FOR EACH ROW
DECLARE
v_cnt NUMBER;
BEGIN
SELECT COUNT(*) INTO v_cnt FROM CF10 WHERE SLE_NO = :NEW.SLE_NO;
IF v_cnt = 0 THEN RAISE_APPLICATION_ERROR(-20101, '판매 없음 ' || :NEW.SLE_NO); END IF;
SELECT COUNT(*) INTO v_cnt FROM CF01 WHERE ITM_NO = :NEW.ITM_NO;
IF v_cnt = 0 THEN RAISE_APPLICATION_ERROR(-20102, '상품 없음 ' || :NEW.ITM_NO); END IF;
IF :NEW.SLE_QTY <= 0 THEN RAISE_APPLICATION_ERROR(-20103, '수량 오류'); END IF;
END;
-- 이번 주 · 11월분 다시 넣기
INSERT INTO CF11 (SLE_NO, ITM_NO, SLE_QTY, SLE_UPRC)
SELECT SLE_NO, ITM_NO, SLE_QTY, SLE_UPRC
FROM CF11_RCV;
COMMIT;
[11월분 다시 넣기 — 세션 통계]
경과 시간 3.84 초
CPU used by this session 3.41 초
recursive calls 91,032
execute count 90,756
session logical reads 238,640
redo size 14.6 MB
[TKPROF — 트리거 안의 두 문장]
SELECT COUNT(*) FROM CF10 WHERE SLE_NO = :B1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Execute 45370 0.61 0.66 0 0 0 0
Fetch 45370 0.38 0.41 0 136110 0 45370
SELECT COUNT(*) FROM CF01 WHERE ITM_NO = :B1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Execute 45370 0.55 0.60 0 0 0 0
Fetch 45370 0.29 0.31 0 45370 0 45370
[감사 점검 — 고아 행 2행의 내력]
CF11에 있는데 CF01에 없는 ITM_NO 1088 · 2행
두 행을 넣은 POS 트랜잭션 3월 14일 10:02:41 INSERT (트리거 통과) · 10:03:20 COMMIT
상품 1088을 지운 정리 배치 3월 14일 10:02:30 DELETE · 10:02:44 COMMIT