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

콜드브루 리콜 영수증 635장을 찾는 데 PK를 180블록 넘게 읽는다

기초SELECT유통87 / 700

상황 ​

원두 공급처가 2023년 12월에 납품한 콜드브루 원액 한 로트를 회수했다. 매장에 안내하려면 그달 콜드브루(1010)가 팔린 영수증 번호를 모두 뽑아야 한다. 품질팀은 같은 조회를 다른 상품으로도 하루 수십 번 돌린다. CF11에는 판매 날짜 컬럼이 없어서, 개발자는 판매번호 앞 여섯 자리(연월)에 LIKE를 걸었다. 개발자는 "PK 인덱스를 타니까 괜찮다"고 한다.

테이블과 인덱스 ​

  • CF11 판매상품: 1,096,708행 · 8,204블록 · SLE_NO는 'YYYYMMDD-NNNN'(앞 8자리가 판매일자) · 2023년 12월 46,322행 · 그중 콜드브루(1010) 635행
  • CF11_PK (SLE_NO, ITM_NO): BLEVEL 2 · 리프 약 4,290블록 · 통계 최신 · 다른 인덱스 없음
  • 영수증 상세(SLE_NO = :v)와 판매 등록이 이 PK를 쓴다

원본 SQL ​

sql
SELECT SLE_NO
  FROM CF11
 WHERE SLE_NO LIKE :v_ym || '%'
   AND ITM_NO = :v_itm
 ORDER BY SLE_NO

실행계획 학습용 예시 · 건수는 적재 데이터(CF11) 그대로 ​

xplan
---------------------------------------------------------------------------------------------
| Id  | Operation         | Name    | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |         |      1 |        |    635 |00:00:00.01 |     183 |
|*  1 |  INDEX RANGE SCAN | CF11_PK |      1 |    623 |    635 |00:00:00.01 |     183 |
---------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access("SLE_NO" LIKE :V_YM||'%' AND "ITM_NO"=:V_ITM)
       filter(("ITM_NO"=:V_ITM AND "SLE_NO" LIKE :V_YM||'%'))

문제 ​

  1. PK 인덱스를 타는데도 183블록을 읽는 이유를 1번 줄의 access와 filter로 설명하시오. 이 LIKE가 어떤 조건으로 쓰였는지도 설명하시오.
  2. 읽는 양을 줄이는 인덱스를 설계해 DDL을 작성하시오. PK의 컬럼 순서를 바꾸는 방법이 왜 답이 아닌지도 설명하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자