Skip to content
튜닝 연습조인 튜닝
JOIN-009

점주 앱의 '오늘 주문' 일곱 건을 보여 주는데 주문을 3,389번 찾아간다

기초SELECT버거159 / 700

상황 ​

점주 앱의 「오늘 주문 내역」은 매장 하나의 그날 주문과 주문 상품을 시각순으로 보여 준다. 점주 200명이 수시로 새로 고쳐서 하루 2만 번 호출된다. 개발자는 "주문상품에도 ORD_DT가 있어서 그걸로 먼저 걸렀다"라고 한다. 아래는 2013-06-14, 매장 SH0137(주문 7건, 주문상품 17줄)의 실행계획이다.

테이블과 인덱스 ​

  • ORD 주문: 1,000,000행 · 22,422블록 · ORD_PK (ORD_NO) · ORD_X01 (ORD_DT, ORD_HMS) · 날짜순 적재 (하루 약 1,370건이 약 31블록에 모여 있다) · 매장 200개
  • ORD_ITEM 주문상품: 2,472,717행 · 55,265블록 · ORD_ITEM_PK (ORD_NO, ITEM_ID) · ORD_ITEM_X01 (ORD_DT, ORD_HMS) · 하루 약 3,390줄
  • ORD_ITEM.ORD_DT는 ORD에서 옮겨 적은 반정규화 컬럼이다 · 매장 번호 SHOP_NO는 ORD에만 있다 · 통계 최신

원본 SQL ​

sql
SELECT /*+ LEADING(i) USE_NL(o) */
       o.ORD_NO, o.ORD_HMS, i.ITEM_ID, i.ORD_ITEM_QTY
  FROM ORD_ITEM i, ORD o
 WHERE i.ORD_DT  = :v_dt
   AND o.ORD_NO  = i.ORD_NO
   AND o.ORD_DT  = :v_dt
   AND o.SHOP_NO = :v_shop
 ORDER BY o.ORD_HMS, i.ITEM_ID

실행계획 학습용 예시 ​

xplan
------------------------------------------------------------------------------------------------------------------
| Id  | Operation                               | Name         | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                        |              |      1 |        |     17 |00:00:00.03 |    3542 |
|   1 |  SORT ORDER BY                          |              |      1 |     17 |     17 |00:00:00.03 |    3542 |
|   2 |   NESTED LOOPS                          |              |      1 |     17 |     17 |00:00:00.03 |    3542 |
|   3 |    NESTED LOOPS                         |              |      1 |   3387 |   3389 |00:00:00.01 |     153 |
|   4 |     TABLE ACCESS BY INDEX ROWID BATCHED | ORD_ITEM     |      1 |   3387 |   3389 |00:00:00.01 |      91 |
|*  5 |      INDEX RANGE SCAN                   | ORD_ITEM_X01 |      1 |   3387 |   3389 |00:00:00.01 |      15 |
|*  6 |     INDEX UNIQUE SCAN                   | ORD_PK       |   3389 |      1 |   3389 |00:00:00.01 |      62 |
|*  7 |    TABLE ACCESS BY INDEX ROWID          | ORD          |   3389 |      1 |     17 |00:00:00.02 |    3389 |
------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   5 - access("I"."ORD_DT"=:V_DT)
   6 - access("O"."ORD_NO"="I"."ORD_NO")
   7 - filter(("O"."ORD_DT"=:V_DT AND "O"."SHOP_NO"=:V_SHOP))

문제 ​

  1. 7번 줄의 Starts와 A-Rows를 비교해, 이 조인이 주문을 몇 번 찾아가서 몇 건을 남기는지 설명하시오.
  2. 두 테이블의 조건이 각각 몇 행을 남기는지 비교해 드라이빙 테이블을 정하고 개선 SQL을 작성하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자