Skip to content
튜닝 연습소트 튜닝과 페이징
SORT-066

「메뉴별 월 판매 추이」 24개월 그래프가 열 때마다 주문상품 5만 5천 블록을 다시 묶는다

중급SELECT버거371 / 700

상황 ​

버거 본사 메뉴팀의 「메뉴별 월 판매 추이」는 메뉴 92종의 최근 24개월 월별 판매 수량을 그래프로 그린다. 메뉴팀 15명이 하루 약 300번 여는데, 열 때마다 2.4초가 걸린다. 이번 달 칸은 지금까지의 숫자가 보여야 하고, 지난달까지의 칸은 매월 2일 새벽의 월 마감 뒤에는 바뀌지 않는다(정정은 이번 달 주문으로 들어온다). 조민우가 인덱스를 만들자고 하자 DBA는 "24개월을 다 묶는 SQL이면 인덱스를 만들어도 FULL이 맞다"라고 했다. 오늘은 2013년 12월 31일이다.

테이블과 인덱스 ​

  • ORD_ITEM 주문상품: 2,472,717행 · 55,265블록 · (ORD_NO, ITEM_ID) 순으로 쌓여 있다(주문번호는 시각 순이라 날짜순과 거의 같다) · ITEM_ID 1 ~ 92 · ORD_DT VARCHAR2(8) 2012-01-01 ~ 2013-12-31 · ORD_ITEM_QTY · 한 달 약 103,000행
  • 인덱스 ORD_ITEM_PK (ORD_NO, ITEM_ID) · ORD_ITEM_X01 (ORD_DT, ORD_HMS): BLEVEL 2 · 리프 약 9,320 · CF 약 55,200 · 통계 최신
  • 주문상품은 POS 결제마다 1 ~ 4줄씩 들어온다

원본 SQL ​

sql
SELECT SUBSTR(ORD_DT, 1, 6) AS YM, ITEM_ID, SUM(ORD_ITEM_QTY) AS QTY
  FROM ORD_ITEM
 WHERE ORD_DT >= :from_ym || '01'          -- :from_ym = '201201' (24개월 전)
 GROUP BY SUBSTR(ORD_DT, 1, 6), ITEM_ID
 ORDER BY YM, ITEM_ID

실행계획 학습용 예시 ​

xplan
-----------------------------------------------------------------------------------------------------------
| Id  | Operation          | Name     | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Used-Mem |
-----------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |          |      1 |        |   2208 |00:00:02.41 |   55265 |          |
|   1 |  SORT GROUP BY     |          |      1 |   2208 |   2208 |00:00:02.41 |   55265 |  178K (0)|
|*  2 |   TABLE ACCESS FULL| ORD_ITEM |      1 |   2472K|   2472K|00:00:00.73 |   55265 |          |
-----------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("ORD_DT">=:FROM_YM||'01')

문제 ​

  1. 24개월 집계에 ORD_ITEM_X01을 쓰지 않고 FULL로 읽는 것이 옳은 까닭을 숫자로 설명하시오.
  2. 화면 요구(이번 달은 지금까지, 지난달까지는 마감 숫자)를 지키면서 화면을 열 때 읽는 양을 줄이도록 SQL과 DDL을 쓰시오.
  3. 고친 구조의 대가와 정합성을 지키는 조건을 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자