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

공통 뷰를 거치는 매장 월 주문 목록이 주문 테이블을 통째로 읽는다

기초SELECT버거280 / 700

상황 ​

버거 본사의 「매장 월 주문 목록」은 매장과 연월을 고르면 그 매장의 한 달 주문을 시간순으로 보여 준다. 슈퍼바이저 30명이 하루 1,500번쯤 열고, 한 번에 0.2초 남짓 걸린다. SQL은 2014년에 월 마감 리포트용으로 만든 공통 뷰 V_ORD_MON을 읽는다. 개발자는 "뷰를 거쳐서 느린 것 같으니 뷰를 빼고 ORD를 직접 읽게 고치겠다"라고 한다.

테이블과 인덱스 ​

  • ORD 주문: 1,000,000행 · 22,422블록 · ORD_DT VARCHAR2(8) '20120101' ~ '20131231' · 매장 200곳 · 한 달 약 41,700건 · 한 매장의 한 달 주문 약 208건
  • 인덱스 ORD_PK (ORD_NO) · ORD_X01 (ORD_DT, ORD_HMS): 날짜순 적재(CF 22,223) · 높이 3 · 한 달치 리프 약 140블록
  • SHOP_NO에는 인덱스가 없다 · 통계 최신
  • 뷰 V_ORD_MON의 정의는 아래 SQL 맨 위와 같다 · 실행계획은 :shop = 'SH0042', :ym = '201306'

원본 SQL ​

sql
-- 공통 뷰 (2014년 월 마감 리포트용)
CREATE OR REPLACE VIEW V_ORD_MON AS
SELECT ORD_NO, SHOP_NO,
       SUBSTR(ORD_DT, 1, 6) AS ORD_YM,
       ORD_DT, ORD_HMS
  FROM ORD;

-- 매장 월 주문 목록
SELECT ORD_NO, ORD_DT, ORD_HMS
  FROM V_ORD_MON
 WHERE SHOP_NO = :shop
   AND ORD_YM  = :ym
 ORDER BY ORD_DT, ORD_HMS;

실행계획 학습용 예시 ​

xplan
---------------------------------------------------------------------------------------------------
| Id  | Operation          | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Used-Mem |
---------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |      1 |        |    208 |00:00:00.21 |   22422 |          |
|   1 |  SORT ORDER BY     |      |      1 |     50 |    208 |00:00:00.21 |   22422 |18432  (0)|
|*  2 |   TABLE ACCESS FULL| ORD  |      1 |     50 |    208 |00:00:00.21 |   22422 |          |
---------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter(("SHOP_NO"=:SHOP AND SUBSTR("ORD_DT",1,6)=:YM))

문제 ​

  1. 실행계획에 뷰를 읽는 줄이 보이지 않는 이유와, 2번 줄 조건이 SUBSTR("ORD_DT",1,6)=:YM으로 바뀐 이유를 설명하시오.
  2. 개발자의 제안(뷰를 빼고 ORD를 직접 읽는다)으로 빨라지는지 판단하고, 화면 SQL을 고쳐 ORD_X01로 한 달만 읽도록 하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자