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

분기 가맹점 집계가 지난주부터 3,253블록에서 22,239블록을 읽는다

기초SELECT버거104 / 700

상황 ​

1년 전 운영본 ORD_RANDOM의 월마감 일(ACC-002) 뒤로, 버거원 개발팀에는 이런 표준이 생겼다. "주문 테이블의 기간 조회가 2주를 넘으면 FULL 힌트를 넣는다(손익분기 16일)." 본사 분석팀의 「분기 가맹점별 주문 건수와 영업일 수」는 운영에 부하를 주지 않으려고 이관 전 보관본 ORD에서 돈다. 지난주 표준 점검에서 이 SQL에도 FULL 힌트가 들어갔는데, 그 뒤로 한 번에 0.02초이던 리포트가 0.1초 가까이 걸린다. 아래는 2012년 1분기(1 ~ 3월)다.

테이블과 인덱스 ​

  • ORD(보관본): 1,000,000행 · 22,422블록 · 주문 시각 순으로 쌓였다 · 2012년 1분기 125,027건(12.5%) · SHOP_NO 200개
  • 인덱스 ORD_X01 (ORD_DT, ORD_HMS): BLEVEL 2 · 리프 3,774 · CLUSTERING_FACTOR 22,223 · 통계 최신
  • 참고: 표준의 근거가 된 ORD_RANDOM(운영본)은 같은 정의의 인덱스 CF가 999,958이다

원본 SQL ​

sql
SELECT /*+ FULL(o) */
       o.SHOP_NO, COUNT(*) AS ord_cnt, COUNT(DISTINCT o.ORD_DT) AS sale_days
  FROM ORD o
 WHERE o.ORD_DT BETWEEN :v_from AND :v_to
 GROUP BY o.SHOP_NO

실행계획 실측 · 교재 04화 (ORD 91일 범위) ​

xplan
----------------------------------------------------------------------------------------
| Id  | Operation          | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |      1 |        |    200 |00:00:00.09 |   22239 |
|   1 |  HASH GROUP BY     |      |      1 |    200 |    200 |00:00:00.09 |   22239 |
|*  2 |   TABLE ACCESS FULL| ORD  |      1 |  22050 |   125K |00:00:00.07 |   22239 |
----------------------------------------------------------------------------------------
   2 - filter(("O"."ORD_DT">=:V_FROM AND "O"."ORD_DT"<=:V_TO))

[힌트를 넣기 전 · 같은 범위]  TABLE ACCESS BY INDEX ROWID BATCHED + INDEX RANGE SCAN ORD_X01 · Buffers 3,253

문제 ​

  1. 운영본에서 만든 '2주' 규칙이 보관본 ORD에서는 왜 맞지 않는지, 두 테이블의 CLUSTERING_FACTOR와 손익분기 계산으로 설명하시오.
  2. SQL을 고치고, 표준을 어떻게 바꿔야 하는지 설명하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자