Skip to content
튜닝 연습DML과 배치 튜닝
DML-013

야간 체인에서 부가세 분리 단계만 여전히 INSERT를 10만 번 실행한다

중급PLSQL한빛유통438 / 700

상황 ​

야간 체인의 SQL 조각은 대부분 한 문장이 됐는데, T3 리포트의 「PL/SQL 호출 통계」 칸을 채우다 보니 「부가세 분리」 단계만 INSERT가 10만 번 실행되고 있었다. 이 단계는 정산 금액을 공급가액과 부가세로 나누고, 나누는 규칙은 회계팀 패키지 PKG_VAT의 프로시저에 있다. 회계팀: "세율과 면세 규칙은 우리 화면도 같은 프로시저를 써요. 패키지는 못 고칩니다." 오과장은 다른 단계처럼 INSERT … SELECT 한 문장으로 바꾸고 싶어 한다.

테이블과 인덱스 ​

  • T_ORD_STLM: 100,000행 · 640블록 · T_ORD: 100,000행 · 896블록 · PK_T_ORD (ORD_SEQ) · 결제 수단 PAY_TP는 T_ORD에 있다.
  • T_STLM_VAT(대상, 이 문제용 테이블): STLM_SEQ · SUPPLY_AMT · VAT_AMT · RULE_CD. 단계를 시작할 때 비운다(TRUNCATE). 인덱스는 없다.
  • PKG_VAT.SPLIT(p_amt IN NUMBER, p_pay_tp IN VARCHAR2, p_dt IN DATE, o_supply OUT NUMBER, o_vat OUT NUMBER, o_rule OUT VARCHAR2): 회계팀 소유다. 안에 SQL은 없고 패키지 안의 세율표(PL/SQL 배열)만 쓴다.

원본 SQL ​

sql
PROCEDURE P3_VAT IS
  v_sup  NUMBER;
  v_vat  NUMBER;
  v_rule VARCHAR2(10);
BEGIN
  EXECUTE IMMEDIATE 'TRUNCATE TABLE T_STLM_VAT';
  FOR r IN (SELECT s.STLM_SEQ, s.STLM_AMT, s.STLM_DT, o.PAY_TP
              FROM T_ORD_STLM s, T_ORD o
             WHERE o.ORD_SEQ = s.ORD_SEQ) LOOP
    PKG_VAT.SPLIT(r.STLM_AMT, r.PAY_TP, r.STLM_DT, v_sup, v_vat, v_rule);   -- 회계팀 규칙
    INSERT INTO T_STLM_VAT (STLM_SEQ, SUPPLY_AMT, VAT_AMT, RULE_CD)
    VALUES (r.STLM_SEQ, v_sup, v_vat, v_rule);
  END LOOP;
  COMMIT;
END;

실행계획 학습용 예시 ​

xplan
[세션 통계 — P3_VAT 한 번 (연습 DB 복사본)]
  경과 시간                 1.02 ~ 1.08 초
  CPU used by this session  0.61 초
  recursive calls           101,342
  execute count             100,031
  session logical reads     약 112,600
  redo size                 약 26.9 MB
  undo change vector size   약 6.4 MB

[TKPROF 모양]
SELECT S.STLM_SEQ, S.STLM_AMT, S.STLM_DT, O.PAY_TP FROM T_ORD_STLM S, T_ORD O WHERE …
  Execute 1 · Fetch 1,001 · rows 100,000 · query 1,536 (HASH JOIN · T_ORD_STLM 640 + T_ORD 896)
INSERT INTO T_STLM_VAT (STLM_SEQ, SUPPLY_AMT, VAT_AMT, RULE_CD) VALUES (:B4, :B3, :B2, :B1)
  Execute 100,000 · rows 100,000 · query 약 1,900 · current 약 109,000

[DBMS_HPROF — 시간이 쓰인 곳]
  INSERT (SQL)          100,000 부름   0.78 초
  PKG_VAT.SPLIT         100,000 부름   0.15 초
  커서 페치                1,001 부름   0.03 초

문제 ​

  1. 이 단계의 일량이 어디서 나오는지 세션 통계와 HPROF로 설명하시오.
  2. INSERT … SELECT 한 문장으로 바로 바꿀 수 없는 이유를 쓰고, 규칙은 그대로 두면서 일량을 줄이도록 다시 작성하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자