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

영수증 찾기 화면이 판매번호로 찾든 판매일자로 찾든 판매 50만 건을 다 읽는다

기초SELECT유통52 / 700

상황 ​

유통 매장 POS의 「영수증 찾기」는 위쪽 콤보에서 '판매번호'나 '판매일자'를 고르고 값을 친다. 화면은 고른 구분을 :v_tp('NO' 또는 'DT')로, 친 값을 :v_key로 넘긴다. 개발자는 SQL을 하나로 쓰려고 비교할 컬럼을 DECODE로 고르게 했다. 매장 다섯 곳에서 하루 수백 번 쓰는데, 찾을 때마다 계산대가 멈칫한다고 한다.

테이블과 인덱스 ​

  • CF10 판매: 500,000행 · 4,583블록 · SLE_NO VARCHAR2(15) '20230601-0308'(판매일자 8자리 + - + 일련번호) · SLE_DT VARCHAR2(8) · SLE_HMS · SHP_NO · 판매번호 순(날짜 순)으로 쌓였다 · 2023-06-01 판매 706건
  • 인덱스 CF10_PK (SLE_NO) · IX_CF10_SLE_DT (SLE_DT): 둘 다 BLEVEL 2 · 통계 최신

원본 SQL ​

sql
SELECT SLE_NO, SLE_DT, SLE_HMS, SLE_DOW, SHP_NO
  FROM CF10
 WHERE DECODE(:v_tp, 'NO', SLE_NO, 'DT', SLE_DT) = :v_key
 ORDER BY SLE_NO DESC

실행계획 학습용 예시 ​

xplan
[판매번호 '20230601-0308'로 찾았을 때 · 판매일자 '20230601'로 찾아도 계획은 같다(706건, Buffers 4,587)]
---------------------------------------------------------------------------------------
| Id  | Operation           | Name | Starts | E-Rows | A-Rows | A-Time      | Buffers |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |      1 |        |      1 | 00:00:00.06 |    4587 |
|   1 |  SORT ORDER BY      |      |      1 |   5000 |      1 | 00:00:00.06 |    4587 |
|*  2 |   TABLE ACCESS FULL | CF10 |      1 |   5000 |      1 | 00:00:00.06 |    4587 |
---------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter(DECODE(:V_TP,'NO',"SLE_NO",'DT',"SLE_DT")=:V_KEY)

문제 ​

  1. 판매번호에도 판매일자에도 인덱스가 있는데 어느 구분으로 찾아도 FULL인 이유를 설명하시오.
  2. 문장 하나(커서 하나)를 유지하면서 고른 구분에 맞는 인덱스로 찾아가도록 SQL을 고치시오. 화면에서 SQL을 둘로 나눠 부르는 방법과도 비교하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자