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

INDEX_SS 힌트를 붙였는데도 「내가 쓴 리뷰」가 리뷰 1만 5천 건을 다 읽는다

기초SELECT이커머스63 / 700

이 문제는 교재 18화 졸업 과제와 같은 이커머스 데이터베이스를 씁니다. 『튜너의 1년』을 순서대로 읽고 있다면 졸업 과제를 먼저 풀고 오세요. 아래 「테이블과 인덱스」 칸에 과제의 답 일부(제약 조건, 인덱스, 통계의 실제 상태)가 나옵니다.

상황 ​

이커머스 앱 마이페이지의 「내가 쓴 리뷰」는 로그인한 고객이 쓴 리뷰를 최신순으로 보여 준다. 하루 약 2만 번 열린다. 개발자는 상품 상세 화면용으로 만든 IX_REVIEWS_PROD_DT를 이 화면에도 쓰려고 INDEX_SS 힌트를 붙였다. 메모에는 "선두 컬럼이 빠져도 SKIP SCAN이면 인덱스를 탈 수 있다고 배웠다"라고 적혀 있다. 그런데 계획은 FULL 그대로다. 아래는 고객 1042(리뷰 5건)로 연 계획이다.

테이블과 인덱스 ​

  • reviews: 15,000행 · 775블록 · review_id PK · product_id(상품 280개) · customer_id(리뷰를 쓴 고객 약 4,000명, 고객당 평균 3.8건, 많아야 14건) · rating · content CLOB(행 안에 저장) · created_at DATE
  • 한 고객의 리뷰는 쓴 날짜가 달라 테이블 곳곳의 서로 다른 블록에 있다
  • 인덱스 PK_REVIEWS (review_id) · IX_REVIEWS_PROD_DT (product_id, created_at): IDX-046에서 상품 상세 화면용으로 만든 인덱스 · BLEVEL 1 · 리프 약 45블록 · 통계 최신
  • 리뷰는 하루 약 40건씩 늘고, 고치거나 지우는 일은 드물다

원본 SQL ​

sql
SELECT /*+ INDEX_SS(r IX_REVIEWS_PROD_DT) */
       r.review_id, r.product_id, r.rating, r.created_at
  FROM reviews r
 WHERE r.customer_id = :v_cust
 ORDER BY r.created_at DESC

실행계획 학습용 예시 ​

xplan
-----------------------------------------------------------------------------------------
| Id  | Operation          | Name    | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |         |      1 |        |      5 |00:00:00.01 |     775 |
|   1 |  SORT ORDER BY     |         |      1 |      4 |      5 |00:00:00.01 |     775 |
|*  2 |   TABLE ACCESS FULL| REVIEWS |      1 |      4 |      5 |00:00:00.01 |     775 |
-----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("R"."CUSTOMER_ID"=:V_CUST)

문제 ​

  1. INDEX_SS 힌트를 붙였는데도 INDEX SKIP SCAN이 나오지 않고 테이블 전체를 읽는 이유를, SKIP SCAN이 가능하려면 무엇이 있어야 하는지로 설명하시오.
  2. 이 화면이 인덱스 범위 스캔으로 처리되도록 인덱스와 SQL을 고치고, 정렬까지 없어지는지 설명하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자