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

정산 10만 건에 고객 등급을 채우는 단계가 적재 단계보다 오래 걸린다

기초MERGE한빛유통436 / 700

상황 ​

정산 화면이 등급별로 묶어 보려고 T_ORD_STLM에 고객 등급 칸(CUS_GD)을 더했고, 야간 체인에 그 칸을 채우는 단계가 하나 생겼다. 체인 시각을 찍어 보니 이 단계가 1.3초로, 정산 10만 건을 넣는 적재 단계(0.1초)보다 오래 걸린다. 배치 담당 오과장: "한 건씩 ROWID로 바로 찾아가니까 제일 빠른 방법 아닌가요?"

테이블과 인덱스 ​

  • T_ORD_STLM: 100,000행 · 640블록. 이 문제에서는 CUS_GD VARCHAR2(1) 칸이 더 있다. 체인 첫 단계(P1)가 매일 밤 비우고 다시 채우므로, 이 단계가 돌 때 CUS_GD는 전부 NULL이다. 인덱스는 없다.
  • M_CUS: 2,000행 · 30블록 · PK_M_CUS (CUS_ID) · 정산의 CUS_ID는 모두 M_CUS에 있다.
  • P1은 INSERT /*+ APPEND */ … SELECT ROWNUM, … FROM T_ORD 한 문장이다(교재 14화 rev02).

원본 SQL ​

sql
-- 야간 체인 ② 정산 등급 채우기
BEGIN
  FOR r IN (SELECT s.ROWID AS rid, c.CUS_GD
              FROM T_ORD_STLM s, M_CUS c
             WHERE c.CUS_ID = s.CUS_ID) LOOP
    UPDATE T_ORD_STLM
       SET CUS_GD = r.CUS_GD
     WHERE ROWID = r.rid;
  END LOOP;
  COMMIT;
END;

실행계획 학습용 예시 ​

xplan
[세션 통계 — ② 한 번]
  경과 시간                 1.28 ~ 1.36 초
  CPU used by this session  1.15 초
  recursive calls           101,046
  execute count             100,021
  session logical reads     약 203,600
  redo size                 약 24.8 MB
  undo change vector size   약 7.9 MB

[TKPROF 모양 — ② 의 두 문장]
SELECT S.ROWID AS RID, C.CUS_GD FROM T_ORD_STLM S, M_CUS C WHERE C.CUS_ID = S.CUS_ID
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Fetch     1001      0.06       0.07          0       1670          0      100000     (HASH JOIN · M_CUS 30 + T_ORD_STLM 640)

UPDATE T_ORD_STLM SET CUS_GD = :B2 WHERE ROWID = :B1
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Execute 100000      0.93       1.02          0     100000     102861      100000     (TABLE ACCESS BY USER ROWID)

문제 ​

  1. ROWID로 바로 찾아가는데도 이 단계가 1.3초 걸리는 이유를 위 통계로 설명하시오.
  2. 같은 결과를 내도록 고치시오. 이 단계 자체를 없앨 수 있는지도 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자