Skip to content
튜닝 연습인덱스 사용 조건
IDX-017

결제일 인덱스도 주문일 인덱스도 있는데 일별 매출 인식 화면이 주문 테이블을 다 읽는다

실전SELECT한빛유통17 / 700

상황 ​

회계 규정상 매출 인식일은 결제일이고, 아직 결제되지 않은 주문은 주문일로 잡는다. 정산팀 「일별 매출 인식」 화면은 이 규정을 NVL 하나로 옮겼다. 정산 담당 8명이 하루 종일 날짜를 바꿔 가며 보고, 매시 정각에는 대사 배치가 최근 7일을 다시 센다. 박팀장은 이렇게 주문했다. "인덱스는 둘 다 있다는데 왜 안 쓰는지, 고칠 방법이 여럿이면 비교해서 하나를 골라 와."

테이블과 인덱스 ​

  • T_ORD: 100,000행 · 896블록 · 하루 136 ~ 137건이 서로 다른 블록에 흩어져 있다
  • ORD_DT DATE(시분초 있음) · PAY_DT DATE(결제일, 결제 전이면 NULL · 지금 미결제 41건) (문제 설정: 2024년 12월 결제 연동 개편 뒤의 모습이다. IDX-004와 같다)
  • 2024년 12월 20일 매출 인식분: 137건(그날 결제된 134건 + 그날 주문했지만 아직 미결제인 3건)
  • 인덱스 IX_T_ORD_DT (ORD_DT) · IX_T_ORD_PAY (PAY_DT): 둘 다 BLEVEL 1 · 리프 265 · 통계 최신
  • 주문 INSERT는 하루 약 140건이고 결제 때마다 PAY_DT를 UPDATE한다. 적재 배치 일부는 INSERT INTO T_ORD VALUES (...)처럼 컬럼 목록 없이 넣는다

원본 SQL ​

sql
SELECT COUNT(*) AS cnt, SUM(ORD_AMT) AS amt
  FROM T_ORD
 WHERE NVL(PAY_DT, ORD_DT) >= TO_DATE(:v_dt, 'YYYYMMDD')
   AND NVL(PAY_DT, ORD_DT) <  TO_DATE(:v_dt, 'YYYYMMDD') + 1

실행계획 학습용 예시 ​

xplan
------------------------------------------------------------------------------------
| Id  | Operation           | Name  | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |       |      1 |        |      1 |00:00:00.02 |     896 |
|   1 |  SORT AGGREGATE     |       |      1 |      1 |      1 |00:00:00.02 |     896 |
|*  2 |   FILTER            |       |      1 |        |    137 |00:00:00.02 |     896 |
|*  3 |    TABLE ACCESS FULL| T_ORD |      1 |    250 |    137 |00:00:00.02 |     896 |
------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter(TO_DATE(:V_DT,'YYYYMMDD')+1>TO_DATE(:V_DT,'YYYYMMDD'))
   3 - filter((NVL("PAY_DT","ORD_DT")>=TO_DATE(:V_DT,'YYYYMMDD') AND
              NVL("PAY_DT","ORD_DT")<TO_DATE(:V_DT,'YYYYMMDD')+1))

문제 ​

  1. 인덱스가 둘 다 있는데 테이블 전체를 읽는 이유를 실행계획에서 찾아 설명하시오.
  2. (가) 조건을 OR로 풀어 두 인덱스를 쓰는 방법, (나) 함수 기반 인덱스, (다) 가상 컬럼과 인덱스를 읽는 양과 대가로 비교하고, 하나를 골라 SQL과 DDL을 작성하시오.
  3. 고른 방법이 원래 SQL과 같은 답을 낸다는 것을 어떻게 확인할지 설명하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자