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

이관 리허설에서 주문상세 단가 채우기만 3초, 다른 여섯 단계는 1초 안쪽이다

기초UPDATE한빛유통656 / 700

상황 ​

구 시스템에서 신 시스템으로 넘어가는 이관 리허설이 토요일에 있었다. 일곱 단계 중 「주문상세 단가 채우기」가 2.9초로 가장 길었다. 본 이관 날에는 단계마다 허용 시간이 정해져 있어서, 오과장이 이 단계를 먼저 봐 달라고 했다. 이관팀은 단가 규칙을 이관 공통 함수 FN_ITM_PRC에 넣어 두고 UPDATE 한 문장으로 채운다. 이관팀의 설명은 "한 문장이니 집합 처리다"라는 것이다.

테이블과 인덱스 ​

  • T_ORD_DET 주문상세: 200,000행 · 896블록 · PK_T_ORD_DET (ORD_SEQ, ORD_DET_NO) · 이관 직후 UNT_PRC는 전부 NULL · 상품 100종
  • M_ITM 상품: 100행 · 5블록 · PK_M_ITM (ITM_ID) · UNT_PRC
  • 주문상세의 상품은 모두 M_ITM에 있다(이관 전 대조 완료) · 리허설 DB는 NOARCHIVELOG · 통계 최신

원본 SQL ​

sql
CREATE OR REPLACE FUNCTION FN_ITM_PRC(p_itm_id M_ITM.ITM_ID%TYPE) RETURN NUMBER IS
  v_prc M_ITM.UNT_PRC%TYPE;
BEGIN
  SELECT UNT_PRC INTO v_prc FROM M_ITM WHERE ITM_ID = p_itm_id;
  RETURN v_prc;
END;
/

UPDATE T_ORD_DET d
   SET d.UNT_PRC = FN_ITM_PRC(d.ITM_ID);

COMMIT;

실행계획 학습용 예시 ​

xplan
[DISPLAY_CURSOR (ALLSTATS LAST)]
-----------------------------------------------------------------------------------------
| Id  | Operation          | Name      | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
-----------------------------------------------------------------------------------------
|   0 | UPDATE STATEMENT   |           |      1 |        |      0 |00:00:02.91 |    206K |
|   1 |  UPDATE            | T_ORD_DET |      1 |        |      0 |00:00:02.91 |    206K |
|   2 |   TABLE ACCESS FULL| T_ORD_DET |      1 |   200K |   200K |00:00:00.04 |     896 |
-----------------------------------------------------------------------------------------

[세션 통계: UPDATE 한 번]
  경과 시간                 2.91 초 (CPU 2.62 초)
  recursive calls           200,014
  execute count             200,005
  consistent gets           401,216
  db block gets             204,977
  redo size                 47.6 MB

[V$SQL: 함수 안의 문장 (dep=1)]
  SELECT UNT_PRC FROM M_ITM WHERE ITM_ID = :B1    EXECUTIONS 200,000 · BUFFER_GETS 400,000

문제 ​

  1. UPDATE 한 문장인데 2.9초가 걸리는 이유를 세션 통계로 설명하시오.
  2. 결과가 바뀌지 않게 다시 작성하고, 고친 뒤에도 줄지 않는 일량은 무엇인지 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자