Skip to content
튜닝 연습옵티마이저와 통계
OPT-002

인덱스를 만들었는데 결제 대기 모니터가 여전히 FULL이다

기초SELECT이커머스592 / 700

이 문제는 교재 18화 졸업 과제와 같은 이커머스 데이터베이스를 씁니다. 『튜너의 1년』을 순서대로 읽고 있다면 졸업 과제를 먼저 풀고 오세요. 아래 「테이블과 인덱스」 칸에 과제의 답 일부(제약 조건, 인덱스, 통계의 실제 상태)가 나옵니다.

상황 ​

결제팀 대시보드의 「결제 대기 주문」 칸은 화면 20개가 10초마다 새로 고친다(하루 약 7만 번). 개발팀이 지난주 (status, order_date) 인덱스를 만들었는데, 돌아온 말은 이랬다. "계획이 그대로 FULL이에요." ora-newshop은 적재 직후 GATHER_SCHEMA_STATS를 기본값으로 한 번 돌린 상태다. 데이터셋 설명서에는 이렇게 적혀 있다. "grade · status 같은 편향 컬럼에 히스토그램"

테이블과 인덱스 ​

  • orders: 34,908행 · 193블록 · status 6종, 이 문제의 분포는 DELIVERED 27,926 · SHIPPED 2,793 · PAID 1,745 · CANCELLED 1,396 · RETURNED 1,034 · PENDING 14
  • 인덱스: PK(order_id) · IX_ORD_ST_DT (status, order_date)(지난주 생성, 높이 2)
  • 통계: 적재 직후 기본값으로 수집(METHOD_OPT = FOR ALL COLUMNS SIZE AUTO) · status NUM_DISTINCT 6 · HISTOGRAM NONE

원본 SQL ​

sql
SELECT order_id, customer_id, order_date, total_amount
  FROM orders
 WHERE status = 'PENDING'
 ORDER BY order_date

실행계획 학습용 예시 ​

xplan
---------------------------------------------------------------------------------------------------
| Id  | Operation          | Name   | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Used-Mem |
---------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |        |      1 |        |     14 |00:00:00.01 |     193 |          |
|   1 |  SORT ORDER BY     |        |      1 |   5818 |     14 |00:00:00.01 |     193 | 2048  (0)|
|*  2 |   TABLE ACCESS FULL| ORDERS |      1 |   5818 |     14 |00:00:00.01 |     193 |          |
---------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("STATUS"='PENDING')

[USER_TAB_COL_STATISTICS — ORDERS]
 COLUMN_NAME   NUM_DISTINCT  HISTOGRAM
 STATUS                   6  NONE

문제 ​

  1. E-Rows 5,818이 어디서 나온 숫자인지 손으로 계산하고, 옵티마이저가 새 인덱스를 두고 FULL을 고른 이유를 쓰시오.
  2. SQL은 그대로 두고 통계로 고치시오. 밤마다 도는 자동 수집도 같은 규칙을 따르게 하고, 그 처방의 대가도 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자