Skip to content
튜닝 연습인덱스 스캔 효율과 테이블 액세스
ACC-059

시간대별 메뉴 판매 리포트를 위해 함수 기반 인덱스를 만들었는데 실행계획이 그대로다

중급DDL버거134 / 700

상황 ​

버거원 상품기획팀의 「시간대별 메뉴 판매」는 기간(보통 한 달)을 고르면 시간대와 메뉴별 판매 수량을 표로 보여 준다. 하루 수십 번 열고, 한 달을 고르면 2,700블록 가까이 읽는다. 조민우는 "GROUP BY에 SUBSTR(ORD_HMS, 1, 2)가 있으니 그 식으로 인덱스를 만들면 된다"며 지난주 함수 기반 인덱스를 만들었다. 그런데 실행계획은 그대로이고, 운영팀은 POS 주문상품 INSERT가 고치는 인덱스가 하나 늘었다고 알려 왔다.

테이블과 인덱스 ​

  • ORD_ITEM 주문상품: 2,472,717행 · 55,265블록 · 주문 시각 순으로 쌓였다 · 한 달 약 103,000행 · POS가 하루 약 3,400행 INSERT
  • 인덱스 ORD_ITEM_PK (ORD_NO, ITEM_ID) · ORD_ITEM_X01 (ORD_DT, ORD_HMS): BLEVEL 2 · 리프 약 9,200블록 · CLUSTERING_FACTOR 약 55,100 · 「일별 주문 조회」도 쓴다
  • 지난주 만든 ORD_ITEM_FX01 (SUBSTR(ORD_HMS, 1, 2), ITEM_ID): 리프 약 5,700블록 · 통계 최신
  • 교재 14화 실측 비율로는 인덱스 하나가 5만 건 적재에 redo 약 11.8MB를 더한다 · POS 하루 3,400행이면 하루 약 0.8MB다

원본 SQL ​

sql
SELECT SUBSTR(ORD_HMS, 1, 2) AS hh, ITEM_ID, SUM(ORD_ITEM_QTY) AS qty
  FROM ORD_ITEM
 WHERE ORD_DT BETWEEN :v_from AND :v_to
 GROUP BY SUBSTR(ORD_HMS, 1, 2), ITEM_ID;

-- 지난주 조민우
CREATE INDEX ORD_ITEM_FX01 ON ORD_ITEM (SUBSTR(ORD_HMS, 1, 2), ITEM_ID);

실행계획 학습용 예시 · 규모는 schemas 그대로 · 리프 수는 어림값 ​

xplan
[2013년 11월 · FX01을 만든 뒤에도 같다]
---------------------------------------------------------------------------------------------------------------
| Id  | Operation                            | Name         | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
---------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                     |              |      1 |        |   1288 |00:00:00.09 |    2690 |
|   1 |  HASH GROUP BY                       |              |      1 |   1288 |   1288 |00:00:00.09 |    2690 |
|   2 |   TABLE ACCESS BY INDEX ROWID BATCHED| ORD_ITEM     |      1 |    98K |   103K |00:00:00.06 |    2690 |
|*  3 |    INDEX RANGE SCAN                  | ORD_ITEM_X01 |      1 |    98K |   103K |00:00:00.02 |     387 |
---------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   3 - access("ORD_DT">=:V_FROM AND "ORD_DT"<=:V_TO)

문제 ​

  1. ORD_ITEM_FX01이 이 리포트에 쓰이지 않는 이유를 함수 기반 인덱스가 어떤 조건에 쓰이는지로 설명하시오.
  2. 이 리포트가 테이블을 읽지 않도록 인덱스를 고치시오. ORD_ITEM_FX01을 어떻게 할지와, POS INSERT가 고치는 인덱스 수가 어떻게 되는지도 설명하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자