Skip to content
튜닝 연습파싱과 바인드 변수
PARSE-010

보정 6,000건을 고치는 주간 배치가 행 수에 비해 CPU를 너무 많이 쓴다

중급PLSQL한빛유통555 / 700

상황 ​

한빛유통은 정산을 월별 보관 테이블(T_ORD_STLM_202201 ~ T_ORD_STLM_202412)에 나눠 둔다. 주간 보정 배치는 보정 요청을 읽어 해당 월 테이블의 정산 금액을 고친다. 월이 테이블 이름에 들어가므로 동적 SQL을 쓴다. 이번 주 보정 6,000건에 9.1초가 걸렸고 그동안 CPU 하나를 거의 다 썼다. 오과장이 물었다. "한 건에 한 행인데, 1초도 안 걸려야 정상 아닌가요?"

테이블과 인덱스 ​

  • T_ORD_STLM_YYYYMM 월별 정산 보관 테이블: T_ORD_STLM을 월마다 나눈 것 · 2022년 1월 ~ 2024년 12월 36개 · 각 약 2,800행 · 20블록 · PK (STLM_SEQ)
  • T_STLM_ADJ 보정 요청: STLM_YM VARCHAR2(6) · STLM_SEQ · ADJ_AMT(음수도 있다) · PROC_YN · 이번 주 미처리 6,000건이 14개월에 걸쳐 있다.
  • CURSOR_SHARING = EXACT

원본 SQL ​

sql
PROCEDURE P_STLM_ADJ IS
BEGIN
  FOR r IN (SELECT STLM_YM, STLM_SEQ, ADJ_AMT
              FROM T_STLM_ADJ
             WHERE PROC_YN = 'N') LOOP
    EXECUTE IMMEDIATE 'UPDATE T_ORD_STLM_' || r.STLM_YM
                   || ' SET STLM_AMT = STLM_AMT + ' || r.ADJ_AMT
                   || ' WHERE STLM_SEQ = ' || r.STLM_SEQ;
  END LOOP;
  UPDATE T_STLM_ADJ SET PROC_YN = 'Y' WHERE PROC_YN = 'N';
  COMMIT;
END;

실행계획 학습용 예시 · 파싱 비율은 교재 11화 실측과 같은 수준 ​

xplan
[10046 → TKPROF · P_STLM_ADJ 한 번 (보정 6,000건)]
UPDATE T_ORD_STLM_202406 SET STLM_AMT = STLM_AMT + -1200 WHERE STLM_SEQ = 61873

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          2          1           1
Misses in library cache during parse: 1

… (같은 모양의 표가 6,000개)

OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse     6031      7.38       7.62          0          0          0           0
Execute   6040      0.71       0.79          0      12410      12380       12000
Fetch       61      0.03       0.03          0        190          0        6000
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total    12132      8.12       8.44          0      12600      12380       18000

Misses in library cache during parse: 6019

[세션 통계]  경과 9.1 초 · parse count (hard) 6,024 · parse time cpu 738 cs · CPU used by this session 812 cs

문제 ​

  1. 행 하나씩 6,000번 고치는 일에 9초가 걸린 이유를 TKPROF로 설명하시오.
  2. 월별 테이블 구조는 그대로 두고 배치를 고치시오. 동적 SQL에서 이어 붙여도 되는 부분과 바인드 변수로 넘겨야 하는 부분을 가려 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자