테마
이 문제는 교재 18화 졸업 과제와 같은 이커머스 데이터베이스를 씁니다. 『튜너의 1년』을 순서대로 읽고 있다면 졸업 과제를 먼저 풀고 오세요. 아래 「테이블과 인덱스」 칸에 과제의 답 일부(제약 조건, 인덱스, 통계의 실제 상태)가 나옵니다.
상품팀: "상품 상세를 열 때마다 아래쪽 리뷰 칸이 늦게 뜬다. 인기 상품일수록 심한 것 같다." 상품 상세는 하루 약 8만 번 열린다. 화면은 상품 하나의 리뷰를 최신순으로 10건 보여 준다(리뷰 번호, 평점, 작성일, 작성 고객). 아래는 상품 100을 열었을 때의 실행계획이다.
reviews: 15,000행 · 775블록(전체 스캔 757). content CLOB 때문에 행이 커서 블록당 약 19행이 들어간다. 인덱스는 PK(review_id) 하나뿐이다.created_at은 DATE(시분초 있음)다. 같은 상품 안에서 created_at이 같은 리뷰는 지금 0쌍이지만, 그렇다는 제약은 없다.product_id에 인덱스가 없다(18화 졸업 과제 때의 상태 그대로다). 통계는 최신이다.SELECT r.review_id, r.rating, r.created_at, r.customer_id
FROM reviews r
WHERE r.product_id = :prod
ORDER BY r.created_at DESC
FETCH FIRST 10 ROWS ONLY
------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Used-Mem |
------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 10 | 00:00:00.01 | 757 | |
|* 1 | VIEW | | 1 | 10 | 10 | 00:00:00.01 | 757 | |
|* 2 | WINDOW SORT PUSHED RANK | | 1 | 54 | 10 | 00:00:00.01 | 757 | 2048 (0) |
|* 3 | TABLE ACCESS FULL | REVIEWS | 1 | 54 | 57 | 00:00:00.01 | 757 | |
------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("from$_subquery$_002"."rowlimit_$$_rownumber"<=10)
2 - filter(ROW_NUMBER() OVER ( ORDER BY INTERNAL_FUNCTION("R"."CREATED_AT") DESC )<=10)
3 - filter("R"."PRODUCT_ID"=:PROD)