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

VIP 캠페인 대상 주문 415건을 세는 데 다른 리포트용 인덱스를 타고 1,400블록 가까이 읽는다

중급SELECT한빛유통131 / 700

상황 ​

마케팅팀은 캠페인을 설계할 때마다 분석 마트 DW_ORD_BIG에서 등급, 지역, 주문 상태, 기간을 조합해 대상 주문의 건수와 금액을 뽑는다. 조건은 캠페인마다 달라서 IN 목록과 부정 조건(<>), 기간이 섞인다. 하루 수백 번 실행된다. 이번 캠페인 조건은 A등급, 지역 RGN05와 RGN07, 취소 제외, 2024년 2분기다. 옵티마이저는 「지역별 월 매출」 리포트용 인덱스를 골랐다.

테이블과 인덱스 ​

  • DW_ORD_BIG 주문 분석 마트: 매일 밤 T_ORD_BIG에 M_CUS의 CUS_GD · RGN_ID · GND_TP와 월 ORD_YM을 붙여 ORD_DT 순으로 다시 만든다(CTAS) · 낮에는 읽기만 한다 · 1,000,000행 · 6,980블록(블록당 약 143행) · ORD_ST는 NOT NULL
  • 분포: CUS_GD A 1% · B 9% · C 90% · RGN_ID 8곳에 12.5%씩 · ORD_ST COMPLETE 90% · PENDING 8% · CANCEL 2% · 2024년 2분기 83,083건
  • 이번 조건의 결과는 415건이다 · A등급 고객 20명은 RGN01과 RGN05에만 10명씩 있고, A등급 고객의 주문은 모두 COMPLETE다
  • 인덱스 IX_DWO_YM_RGN (ORD_YM, RGN_ID): 「지역별 월 매출」 리포트용 B-tree · BLEVEL 2 · 리프 약 2,900블록 · 다른 인덱스는 없다 · 통계 최신

원본 SQL ​

sql
SELECT COUNT(*) AS ord_cnt, SUM(ORD_AMT) AS ord_amt
  FROM DW_ORD_BIG
 WHERE CUS_GD = 'A'
   AND RGN_ID IN ('RGN05', 'RGN07')
   AND ORD_ST <> 'CANCEL'
   AND ORD_YM BETWEEN '202404' AND '202406'

실행계획 학습용 예시 · 조합 건수는 적재 스크립트의 MOD 규칙에서 센 값 · 비트맵 블록 수는 어림값 ​

xplan
---------------------------------------------------------------------------------------------------------------
| Id  | Operation                            | Name          | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
---------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                     |               |      1 |        |      1 |00:00:00.03 |    1378 |
|   1 |  SORT AGGREGATE                      |               |      1 |      1 |      1 |00:00:00.03 |    1378 |
|*  2 |   TABLE ACCESS BY INDEX ROWID BATCHED| DW_ORD_BIG    |      1 |    204 |    415 |00:00:00.03 |    1378 |
|*  3 |    INDEX RANGE SCAN                  | IX_DWO_YM_RGN |      1 |  20770 |  20770 |00:00:00.01 |     218 |
---------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter(("CUS_GD"='A' AND "ORD_ST"<>'CANCEL'))
   3 - access("ORD_YM">='202404' AND "ORD_YM"<='202406')
       filter(("RGN_ID"='RGN05' OR "RGN_ID"='RGN07'))

문제 ​

  1. 3번 줄이 20,770건을 넘기고 2번 줄이 그중 415건만 남기는 이유를 access와 filter로 설명하시오. 이 마트에 캠페인 조합마다 결합 B-tree 인덱스를 만드는 방법이 맞지 않는 이유도 설명하시오.
  2. IN 목록, 부정 조건, 기간이 섞인 조합을 인덱스만으로 좁힐 수 있도록 인덱스를 설계해 DDL을 작성하시오. 고친 실행계획에서 각 조건이 어떤 연산으로 처리되는지와, 건수만 셀 때는 무엇이 달라지는지 설명하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자