Skip to content
튜닝 연습PL/SQL과 사용자 정의 함수
PLSQL-041

DW 전송 표시 한 칸을 고쳤을 뿐인데 판매상품 정정 이력이 110만 행 늘었다

기초DDL유통691 / 700

상황 ​

본사 유통은 2019년 회계 감사 지적 뒤로, 판매상품의 수량이나 단가를 정정하면 정정 전후 값을 CF11_HIS에 남긴다. 이 일은 트리거 TRG_CF11_HIS가 한다. 이번 달 DW 서버를 바꾸면서 판매상품 전체를 다시 보내려고 전송 표시(DW_SND_YN)를 110만 행 모두 'N'으로 고쳤다. UPDATE 한 문장이 41초 걸렸고 CF11_HIS가 1,096,708행 늘었다. 감사팀이 물었다. "정정이 110만 건이라는데 무슨 일인가요?"

테이블과 인덱스 ​

  • CF11 판매상품: 1,096,708행 · 8,204블록 · CF11_PK (SLE_NO, ITM_NO) · SLE_QTY와 SLE_UPRC는 NOT NULL
  • DW_SND_YN CHAR(1)(이 문제용): DW로 보낸 행은 'Y'다. 밤마다 DW 전송 작업이 새 판매상품 3,000줄 안팎을 보내고 'Y'로 고친다.
  • CF11_HIS 판매상품 정정 이력(이 문제용): HIS_DT · SLE_NO · ITM_NO · OLD_QTY · NEW_QTY · OLD_UPRC · NEW_UPRC · 인덱스 없음 · 이번 일 전에 3,212,560행이었다
  • ERP의 「판매상품 정정」 화면은 한 줄을 저장할 때 SLE_QTY, SLE_UPRC, DW_SND_YN을 모두 SET에 넣는다. 정정한 줄은 DW로 다시 보내야 해서 'N'으로 되돌린다. 정정은 한 달에 수십 건이다.

원본 SQL ​

sql
-- 2019년 트리거
CREATE OR REPLACE TRIGGER TRG_CF11_HIS
AFTER UPDATE ON CF11
FOR EACH ROW
BEGIN
  INSERT INTO CF11_HIS (HIS_DT, SLE_NO, ITM_NO, OLD_QTY, NEW_QTY, OLD_UPRC, NEW_UPRC)
  VALUES (SYSDATE, :OLD.SLE_NO, :OLD.ITM_NO, :OLD.SLE_QTY, :NEW.SLE_QTY, :OLD.SLE_UPRC, :NEW.SLE_UPRC);
END;
/

-- DW 서버 교체 · 전체 재전송 표시
UPDATE CF11 SET DW_SND_YN = 'N';
COMMIT;

실행계획 학습용 예시 ​

xplan
[세션 통계 — UPDATE CF11 SET DW_SND_YN = 'N' (1,096,708행)]
                               운영 (트리거 있음)     시험 DB (트리거 없음)
  경과 시간                         41.6 초                6.3 초
  recursive calls                1,097,215                   86
  execute count                  1,097,190                    9
  session logical reads          2,391,206            1,127,904
  redo size                         486 MB               214 MB
  CF11_HIS 증가                  1,096,708행                  —

[TKPROF — 트리거 안의 INSERT (dep=1)]
INSERT INTO CF11_HIS (HIS_DT, SLE_NO, ITM_NO, OLD_QTY, NEW_QTY, OLD_UPRC, NEW_UPRC)
VALUES (SYSDATE, :B6, :B5, :B4, :B3, :B2, :B1)

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute 1096708    24.10      26.92          0       5834    1152630     1096708

[CF11_HIS — 이번 일 전 3,212,560행]
  OLD_QTY <> NEW_QTY 또는 OLD_UPRC <> NEW_UPRC 인 행             2,140
  두 값이 모두 같은 행 (밤마다 DW 전송 표시를 고칠 때 생긴 행)  3,210,420

문제 ​

  1. 전송 표시 한 칸을 고친 UPDATE가 41초 걸리고 정정 이력이 110만 행 늘어난 이유를 설명하시오.
  2. 수량이나 단가가 실제로 바뀐 행만 이력에 남도록 트리거를 고치시오. 정정 화면처럼 칸을 모두 SET에 넣는 UPDATE도 고려하시오.
  3. 이미 쌓인 이력은 어떻게 할지 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자