테마
이 문제는 교재 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 DATEPK_REVIEWS (review_id) · IX_REVIEWS_PROD_DT (product_id, created_at): IDX-046에서 상품 상세 화면용으로 만든 인덱스 · BLEVEL 1 · 리프 약 45블록 · 통계 최신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
-----------------------------------------------------------------------------------------
| 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)
INDEX_SS 힌트를 붙였는데도 INDEX SKIP SCAN이 나오지 않고 테이블 전체를 읽는 이유를, SKIP SCAN이 가능하려면 무엇이 있어야 하는지로 설명하시오.