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

디버깅을 마친 다음 날부터 판매 전표 검증이 두 배 넘게 걸린다

기초DDL유통669 / 700

상황 ​

본사 유통의 야간 「판매 전표 검증」은 판매 전표 50만 건을 읽어 형식 오류(시각 범위, 요일 불일치, 전표 번호 형식)를 찾는다. 지난주 수요일 조민우가 검증 규칙 하나를 고치면서, 디버거로 한 줄씩 따라가 보려고 프로시저를 아래 마지막 문장처럼 다시 컴파일했다. 다음 날부터 0.41초이던 단계가 0.97초가 됐다. 소스는 그 뒤로 한 줄도 바뀌지 않았고, 오류 건수도 그대로다.

테이블과 인덱스 ​

  • CF10 판매: 500,000행 · 4,583블록 · SLE_NO VARCHAR2(15) · SLE_DT VARCHAR2(8) · SLE_HMS · SLE_DOW · SHP_NO
  • CF10_ERR(오류 기록, 이 문제용): SLE_NO · ERR_CD · 하룻밤 오류는 수십 건이라 배열에 모았다가 끝에 한 번 넣는다
  • PKG_SLE_RULE: 검증 규칙을 계산만 하는 패키지(SQL 없음)
  • 인스턴스 기본값은 PLSQL_OPTIMIZE_LEVEL = 2다.

원본 SQL ​

sql
PROCEDURE CHK_SLE_SLIP IS
  TYPE t_err IS TABLE OF CF10_ERR%ROWTYPE INDEX BY PLS_INTEGER;
  v_err t_err;
  n     PLS_INTEGER := 0;
BEGIN
  FOR r IN (SELECT SLE_NO, SLE_DT, SLE_HMS, SLE_DOW, SHP_NO FROM CF10) LOOP
    IF NOT PKG_SLE_RULE.IS_VALID(r.SLE_NO, r.SLE_DT, r.SLE_HMS, r.SLE_DOW) THEN
      n := n + 1;
      v_err(n).SLE_NO := r.SLE_NO;
      v_err(n).ERR_CD := PKG_SLE_RULE.LAST_ERR;
    END IF;
  END LOOP;
  FORALL i IN 1 .. n
    INSERT INTO CF10_ERR VALUES v_err(i);
  COMMIT;
END;

-- 지난주 수요일, 디버깅하려고 돌린 문장
ALTER PROCEDURE CHK_SLE_SLIP COMPILE PLSQL_OPTIMIZE_LEVEL = 1;

실행계획 학습용 예시 ​

xplan
[USER_PLSQL_OBJECT_SETTINGS — 오늘]
  NAME           TYPE           PLSQL_OPTIMIZE_LEVEL   PLSQL_CODE_TYPE
  CHK_SLE_SLIP   PROCEDURE                         1   INTERPRETED
  PKG_SLE_RULE   PACKAGE BODY                      2   INTERPRETED

[TKPROF — 구동 커서 SELECT SLE_NO, SLE_DT, SLE_HMS, SLE_DOW, SHP_NO FROM CF10]
            call      count       cpu    elapsed      query        rows
  지난 화요일 Fetch      5001      0.10       0.11       9584      500000
  오늘        Fetch    500001      0.62       0.66     500004      500000

[세션 통계 — 한 번]
                  경과      recursive calls   session logical reads   오류 기록
  지난 화요일     0.41 초          5,012                 9,602             37건
  오늘            0.97 초        500,012               500,021             37건

문제 ​

  1. 소스가 그대로인데 느려진 이유를 TKPROF와 USER_PLSQL_OBJECT_SETTINGS로 설명하시오.
  2. 되돌리는 문장을 쓰고, 같은 일이 다시 생기지 않게 할 방법을 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자