Skip to content
튜닝 연습서브쿼리와 쿼리 변환
SUBQ-036

늘 0건인 「빈 영수증 점검」이 10분마다 1.6초씩 돌며 TEMP를 쓴다

중급SELECT버거271 / 700

상황 ​

본사 운영실의 「빈 영수증 점검」은 POS가 주문 헤더만 보내고 주문상품을 보내지 못한 주문을 찾는다(전송 오류 감지). 운영실 PC가 10분마다 그날 주문을 점검하는데, 결과는 거의 늘 0건이다. 그런데 한 번에 1.6초가 걸리고, 점검이 돌 때마다 DB 서버의 TEMP 사용량 그래프가 솟는다. 오과장: "찾을 게 없으면 빨리 끝나야 하는 것 아닌가."

테이블과 인덱스 ​

  • ORD 주문: 1,000,000행 · 22,422블록 · ORD_PK (ORD_NO) · ORD_X01 (ORD_DT, ORD_HMS) · 날짜순 적재 · 하루 약 1,370건(아래 계획은 :v_dt = '20131230', 1,371건)
  • ORD_ITEM 주문상품: 2,472,717행 · 55,265블록 · ORD_ITEM_PK (ORD_NO, ITEM_ID): BLEVEL 2 · 리프 약 6,200블록 · ORD_ITEM_X01 (ORD_DT, ORD_HMS) · 주문당 1 ~ 4줄
  • ORD_NO는 주문 일시 순으로 매겨져 있어, 하루치 주문의 주문상품은 ORD_ITEM_PK의 이웃한 리프 몇 개에 모여 있다
  • 통계 최신 · PGA는 자동 관리(정렬 하나에 약 20MB까지 메모리)

원본 SQL ​

sql
SELECT ORD_NO FROM ORD WHERE ORD_DT = :v_dt
MINUS
SELECT ORD_NO FROM ORD_ITEM

실행계획 학습용 예시 ​

xplan
----------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                             | Name        | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads | Writes | Used-Mem | Used-Tmp |
----------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                      |             |      1 |        |      0 |00:00:01.62 |    6241 |  4870 |   4870 |          |          |
|   1 |  MINUS                                |             |      1 |        |      0 |00:00:01.62 |    6241 |  4870 |   4870 |          |          |
|   2 |   SORT UNIQUE                         |             |      1 |   1370 |   1371 |00:00:00.01 |      37 |     0 |      0 |   59K (0)|          |
|   3 |    TABLE ACCESS BY INDEX ROWID BATCHED| ORD         |      1 |   1370 |   1371 |00:00:00.01 |      37 |     0 |      0 |          |          |
|*  4 |     INDEX RANGE SCAN                  | ORD_X01     |      1 |   1370 |   1371 |00:00:00.01 |       6 |     0 |      0 |          |          |
|   5 |   SORT UNIQUE                         |             |      1 |   2472K|   1000K|00:00:01.60 |    6204 |  4870 |   4870 | 2148K (1)|    39M   |
|   6 |    INDEX FAST FULL SCAN               | ORD_ITEM_PK |      1 |   2472K|   2472K|00:00:00.23 |    6204 |     0 |      0 |          |          |
----------------------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   4 - access("ORD_DT"=:V_DT)

문제 ​

  1. 결과가 0건인데도 6,241블록을 읽고 TEMP를 쓰는 까닭을 실행계획 5번과 6번 줄로 설명하시오. MINUS의 두 갈래가 서로 무엇을 모르는지도 설명하시오.
  2. 그날 주문의 주문상품만 확인하도록 SQL을 고치고, 고친 계획이 왜 주문마다 첫 줄만 보고 멈출 수 있는지 설명하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자