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

인덱스 승인서의 예상 크기와 예상 블록 칸을 비워 냈다가 반려됐다

중급DDL버거145 / 700

상황 ​

버거원 상품기획팀이 「메뉴 판매 내역」 화면을 새로 연다. 메뉴 하나와 기간(보통 한 달)을 고르면 그 메뉴가 팔린 주문을 시각순으로 보여 주고, 프로모션 효과를 볼 때는 파일로 내려받는다. 기획자 여섯 명이 하루 수백 번 열 것이라고 한다. 조민우가 (ITEM_ID, ORD_DT) 인덱스 승인서(A안)를 올렸는데 박팀장이 반려했다. "예상 크기, 높이, 화면 예상 블록, 적재 비용 칸이 비어 있다. 만들기 전에 어림해서 채워 와라. 화면이 쓰는 컬럼을 다 담는 B안 (ITEM_ID, ORD_DT, ORD_HMS, ORD_NO, ORD_ITEM_QTY)도 같은 칸으로 비교해서."

테이블과 인덱스 ​

  • ORD_ITEM 주문상품: 2,472,717행 · 55,265블록(블록당 약 45행) · 주문 날짜순으로 쌓였다 · ITEM_ID NUMBER 1 ~ 92에 고르게 분포(상품당 약 26,900행, 하루 약 37행) · ORD_DT VARCHAR2(8) · ORD_HMS VARCHAR2(6) · ORD_ITEM_QTY NUMBER(1 ~ 9)
  • 2013-11-15 하루 주문상품 약 3,430행 · 2013년 11월 약 102,900행 · 그중 자이언트더블버거(84) 1,121행
  • 인덱스 ORD_ITEM_PK (ORD_NO, ITEM_ID) · ORD_ITEM_X01 (ORD_DT, ORD_HMS): BLEVEL 2 · 리프 약 9,300블록 · CLUSTERING_FACTOR 약 55,200 · 통계 최신
  • 매일 03:00에 전날 주문상품 약 3,400행을 인덱스를 켠 채 일반 INSERT로 더한다
  • 어림에 쓸 값: 블록 8KB에서 인덱스가 쓰는 공간은 약 7,200바이트(PCTFREE 10)다 · 항목 하나는 '컬럼 값 + 컬럼마다 길이 1바이트 + ROWID 7바이트 + 머리 약 4바이트'다 · ITEM_ID와 ORD_ITEM_QTY는 값이 2바이트, ORD_NO는 4바이트, ORD_DT는 8바이트, ORD_HMS는 6바이트다 · 브랜치 블록 하나는 아래 블록을 수백 개 가리킨다
  • 참고(교재 04화 실측): 인덱스가 하나 늘면 행 하나를 넣을 때 블록 변경이 약 2회, redo가 약 236바이트 붙는다

원본 SQL ​

sql
-- 「메뉴 판매 내역」 (하루 수백 번)
SELECT ORD_DT, ORD_HMS, ORD_NO, ORD_ITEM_QTY
  FROM ORD_ITEM
 WHERE ITEM_ID = :v_item
   AND ORD_DT BETWEEN :v_from AND :v_to
 ORDER BY ORD_DT, ORD_HMS;

-- 조민우 승인서 A안 (예상 크기 · 높이 · 화면 예상 블록 · 적재 비용 : 빈칸)
CREATE INDEX ORD_ITEM_X03 ON ORD_ITEM (ITEM_ID, ORD_DT);

실행계획 학습용 예시 · 인덱스 규모는 교재 04화 실측 비례 ​

xplan
[지금 · 자이언트더블버거 2013년 11월]
------------------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name         | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |              |      1 |        |   1121 |00:00:00.07 |    2687 |
|*  1 |  FILTER                      |              |      1 |        |   1121 |00:00:00.07 |    2687 |
|*  2 |   TABLE ACCESS BY INDEX ROWID| ORD_ITEM     |      1 |    110 |   1121 |00:00:00.07 |    2687 |
|*  3 |    INDEX RANGE SCAN          | ORD_ITEM_X01 |      1 |  10107 |    102K|00:00:00.01 |     390 |
------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter(:V_FROM<=:V_TO)
   2 - filter("ITEM_ID"=:V_ITEM)
   3 - access("ORD_DT">=:V_FROM AND "ORD_DT"<=:V_TO)
(X01 순서가 ORDER BY와 같아 정렬은 없다)

[승인서 양식]  예상 크기(리프 블록 · MB) · 높이(BLEVEL) · 화면 예상 블록 · 적재 비용 · 전제하는 컬럼

문제 ​

  1. A안과 B안의 항목 크기, 리프 블록 수, 크기(MB), 높이를 어림하시오. 어림하는 방법이 맞는지 X01의 리프 9,300블록으로 검산하시오.
  2. 두 안으로 이 화면이 각각 몇 블록을 읽을지 어림하시오. A안의 CLUSTERING_FACTOR가 어느 정도일지, 테이블이 날짜순으로 쌓였는데도 왜 그런지 설명하시오.
  3. 두 안의 적재 비용을 비교하고 하나를 골라 승인서를 채우시오. DDL도 작성하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자