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

의심 주문 열두 건의 상품을 보여 주는 점검 화면이 주문상품 5만 블록을 통째로 읽는다

중급SELECT버거684 / 700

상황 ​

버거 본사 감사팀의 「환불 의심 주문 점검」 화면은 매장과 날짜를 고르면 의심 주문과 그 주문의 상품을 보여 준다. 의심 주문을 고르는 규칙(같은 계산대의 연속 취소, 마감 직전 대량 주문 등)은 PL/SQL 패키지에 있고, 파이프라인 함수 PKG_AUDIT.FN_SUSPECT_ORD가 주문 번호를 돌려준다. 의심 주문은 보통 열 건 안팎인데 화면은 2초쯤 걸린다. 감사팀은 하루 150번쯤 연다. 개발자는 "함수는 0.01초에 끝난다"라고 한다.

테이블과 인덱스 ​

  • ORD_ITEM 주문상품: 2,472,717행 · 55,265블록 · ORD_ITEM_PK (ORD_NO, ITEM_ID) 높이 3 · 주문 한 건에 평균 2.5행 · 통계 최신
  • T_ORD_NO_TAB: SQL 컬렉션 타입(TABLE OF NUMBER) · FN_SUSPECT_ORD는 이 타입을 PIPELINED로 돌려준다
  • 함수 안 SQL은 그 매장의 하루치 주문만 읽는다(호출 한 번에 44블록)
  • DB 블록 크기 8KB

원본 SQL ​

sql
SELECT s.COLUMN_VALUE AS ORD_NO, i.ITEM_ID, i.ORD_ITEM_QTY
  FROM TABLE(PKG_AUDIT.FN_SUSPECT_ORD(:shop_no, :dt)) s,
       ORD_ITEM i
 WHERE i.ORD_NO = s.COLUMN_VALUE
 ORDER BY s.COLUMN_VALUE, i.ITEM_ID;

실행계획 학습용 예시 ​

xplan
[DISPLAY_CURSOR (ALLSTATS LAST) · :shop_no = 'SH0117', :dt = '20131224']
----------------------------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name           | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Used-Mem |
----------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |                |      1 |        |     31 |00:00:01.93 |   55265 |          |
|   1 |  SORT ORDER BY                      |                |      1 |  20197 |     31 |00:00:01.93 |   55265 |  2048  (0)|
|*  2 |   HASH JOIN                         |                |      1 |  20197 |     31 |00:00:01.93 |   55265 | 1236K (0)|
|   3 |    COLLECTION ITERATOR PICKLER FETCH| FN_SUSPECT_ORD |      1 |   8168 |     12 |00:00:00.01 |       0 |          |
|   4 |    TABLE ACCESS FULL                | ORD_ITEM       |      1 |  2472K |  2472K |00:00:00.61 |   55265 |          |
----------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("I"."ORD_NO"=VALUE(KOKBF$))

[세션 통계: 화면 한 번]  session logical reads 55,309 (함수 안 SQL 44 포함) · 경과 1.94 초

문제 ​

  1. 의심 주문이 12건인데 주문상품을 통째로 읽은 이유를 실행계획의 E-Rows로 설명하시오. 8,168이라는 숫자가 어디서 왔는지도 쓰시오.
  2. 의심 주문 규칙은 함수에 둔 채로 SQL을 고치시오. 고친 방법의 부작용과 다른 방법 하나를 견주어 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자