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

「작년 같은 날」 칸 하나를 열 때마다 판매 2년 치를 다 읽는다

기초SELECT유통35 / 700

상황 ​

유통 매장 점장 화면의 「작년 같은 날」 칸은 오늘과 월일이 같은 날의 판매를 올해와 작년으로 나눠 매장별 건수로 보여 준다. 매장 다섯 곳의 점장과 본사 영업팀이 하루 수백 번 연다. 개발자는 이렇게 말한다. "연도만 빼고 월일이 같은 날을 찾아야 해서 앞에 %를 붙였다. 날짜 인덱스는 있는데 안 탄다." 아래는 6월 1일(:v_mmdd = '0601')에 연 계획이다.

테이블과 인덱스 ​

  • CF10 판매: 500,000행 · 4,583블록(전체 스캔 4,510) · 2022-01-01 ~ 2023-12-31 · 모든 컬럼 NOT NULL
  • SLE_DT VARCHAR2(8) '20230601' · 하루 596 ~ 793건(2022-06-01은 688건, 2023-06-01은 706건) · 하루치 판매는 테이블 약 26블록 안에 모여 있다
  • 인덱스 CF10_PK (SLE_NO) · IX_CF10_SLE_DT (SLE_DT): BLEVEL 2 · 리프 1,393 · 통계 최신
  • 화면은 올해 연도(:v_year, 지금은 '2023')와 월일(:v_mmdd)을 넘긴다

원본 SQL ​

sql
SELECT SLE_DT, SHP_NO, COUNT(*) AS sle_cnt
  FROM CF10
 WHERE SLE_DT LIKE '%' || :v_mmdd
 GROUP BY SLE_DT, SHP_NO
 ORDER BY SLE_DT, SHP_NO

실행계획 학습용 예시 ​

xplan
-------------------------------------------------------------------------------------
| Id  | Operation          | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |      1 |        |     10 |00:00:00.05 |    4510 |
|   1 |  SORT GROUP BY     |      |      1 |   3650 |     10 |00:00:00.05 |    4510 |
|*  2 |   TABLE ACCESS FULL| CF10 |      1 |  25000 |   1394 |00:00:00.05 |    4510 |
-------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("SLE_DT" LIKE '%'||:V_MMDD)

문제 ​

  1. IX_CF10_SLE_DT가 있는데도 TABLE ACCESS FULL로 처리되는 이유를 Predicate Information으로 설명하시오.
  2. 결과가 바뀌지 않게 SQL을 고쳐 두 날짜의 범위만 읽도록 하시오. 화면이 '해마다 같은 날'을 몇 년 치든 보여 달라고 바뀌면 어떻게 할지도 설명하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자