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

5,826블록짜리 테이블을 파일로 내리는데 논리 읽기가 100만이 넘는다

기초PLSQL한빛유통666 / 700

상황 ​

회계팀은 분기마다 외부 감사인에게 「주문 원장 추출 파일」을 보낸다. 2020년에 강도현이 만든 프로시저가 T_ORD_BIG 100만 건을 한 줄씩 파일에 쓴다(UTL_FILE). 이번 분기에는 감사 일정이 당겨져서 파일을 하루에도 몇 번씩 다시 뽑는다. DBA가 한 번 돌린 세션 통계와 TKPROF를 보내 왔다. "테이블은 5,826블록인데 논리 읽기가 100만이 넘어요. 파일 하나 쓰는데 왜 이렇게 읽죠?"

테이블과 인덱스 ​

  • T_ORD_BIG: 1,000,000행 · 5,826블록 · 인덱스 없음 · 통계 최신
  • 파일은 디렉터리 객체 AUDIT_DIR에 쓴다. 한 줄은 약 60바이트다.
  • 프로시저는 기본값(PLSQL_OPTIMIZE_LEVEL = 2)으로 컴파일되어 있다.

원본 SQL ​

sql
PROCEDURE EXP_ORD_AUDIT(p_file VARCHAR2) IS
  CURSOR c IS
    SELECT ORD_SEQ, CUS_ID, ORD_DT, ORD_ST, ORD_AMT
      FROM T_ORD_BIG;
  r  c%ROWTYPE;
  f  UTL_FILE.FILE_TYPE;
BEGIN
  f := UTL_FILE.FOPEN('AUDIT_DIR', p_file, 'w', 32767);
  OPEN c;
  LOOP
    FETCH c INTO r;                          -- 한 건씩
    EXIT WHEN c%NOTFOUND;
    UTL_FILE.PUT_LINE(f, r.ORD_SEQ || '|' || r.CUS_ID || '|' ||
                         TO_CHAR(r.ORD_DT, 'YYYYMMDD') || '|' || r.ORD_ST || '|' || r.ORD_AMT);
  END LOOP;
  CLOSE c;
  UTL_FILE.FCLOSE(f);
END;

실행계획 학습용 예시 ​

xplan
[세션 통계 — EXP_ORD_AUDIT 한 번 (V$MYSTAT 증가분)]
  경과 시간                  2.86 ~ 2.97 초
  CPU used by this session   2.74 초
  session logical reads      1,000,015
  recursive calls            1,000,008
  execute count              6

[TKPROF — 구동 커서]
SELECT ORD_SEQ, CUS_ID, ORD_DT, ORD_ST, ORD_AMT FROM T_ORD_BIG

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          0          0           0
Fetch   1000001      1.21       1.24          0    1000003          0     1000000
------- -------  -------- ---------- ---------- ---------- ----------  ----------
total   1000003      1.21       1.24          0    1000003          0     1000000

Rows (1st)  Row Source Operation
----------  ---------------------------------------------------
   1000000  TABLE ACCESS FULL T_ORD_BIG (cr=1000003 pr=0 pw=0)

문제 ​

  1. 논리 읽기가 테이블 블록 수의 170배가 넘는 이유를 TKPROF의 Fetch 줄로 설명하시오.
  2. 파일 내용이 바뀌지 않게 프로시저를 고치시오. 커서 FOR 루프로 바꾸는 안과 비교해 어느 쪽을 고를지도 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자