Skip to content
튜닝 연습소트 튜닝과 페이징
SORT-010

「최근 리뷰 10건」은 12블록인데 상단 배지 「마지막 5점 리뷰」가 59블록을 읽는다

중급SELECT이커머스315 / 700

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

상황 ​

SORT-002에서 상품 상세의 「최근 리뷰 10건」을 인덱스로 고친 뒤 그 칸은 12블록으로 줄었다. 이번에 상품팀이 상세 상단에 「마지막 5점 리뷰: 3일 전」 배지를 더했다. 상품 상세는 하루 약 8만 번 열린다. 배지 SQL은 MAX 한 줄인데 실행계획을 보니 리뷰 칸보다 다섯 배쯤 무겁다. 개발자는 "MAX는 인덱스 끝만 읽는다고 배웠다"라고 한다. 다음 달에는 「마지막 1점 리뷰」 배지도 붙일 예정이다.

테이블과 인덱스 ​

  • reviews: 15,000행 · 775블록 · 블록당 약 19행(content CLOB) · 상품당 34 ~ 76건 · 상품 100은 57건이고 테이블 곳곳의 블록에 흩어져 있다
  • rating 1 ~ 5: 5점 약 38% · 1점 약 6% · 상품 100의 5점 리뷰는 22건이다
  • 인덱스 IX_REV_PROD_DT (product_id, created_at, review_id): SORT-002에서 만든 인덱스 · BLEVEL 1 · 리프 약 60블록 · PK(review_id) · 통계 최신

원본 SQL ​

sql
SELECT MAX(created_at) AS last_5star
  FROM reviews
 WHERE product_id = :prod
   AND rating = 5

실행계획 학습용 예시 · 교재 18화 E4 규모 ​

xplan
--------------------------------------------------------------------------------------------------------------
| Id  | Operation                            | Name           | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
--------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                     |                |      1 |        |      1 |00:00:00.01 |      59 |
|   1 |  SORT AGGREGATE                      |                |      1 |      1 |      1 |00:00:00.01 |      59 |
|*  2 |   TABLE ACCESS BY INDEX ROWID BATCHED| REVIEWS        |      1 |     11 |     22 |00:00:00.01 |      59 |
|*  3 |    INDEX RANGE SCAN                  | IX_REV_PROD_DT |      1 |     54 |     57 |00:00:00.01 |       2 |
--------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("RATING"=5)
   3 - access("PRODUCT_ID"=:PROD)

[참고 : 같은 인덱스 · 조건이 product_id 하나일 때]
  SELECT MAX(created_at) FROM reviews WHERE product_id = :prod
  → SORT AGGREGATE · FIRST ROW · INDEX RANGE SCAN (MIN/MAX) IX_REV_PROD_DT · Buffers 2

문제 ​

  1. 같은 인덱스로 MAX(created_at)가 2블록에 끝나는 경우와 59블록을 읽는 이 SQL의 차이를 실행계획 2번, 3번 줄로 설명하시오.
  2. 새 인덱스를 더하는 안, 기존 인덱스에 컬럼을 덧붙이는 안, 인덱스는 그대로 두고 SQL만 바꾸는 안을 비교하고 하나를 골라 SQL과 DDL로 쓰시오. 1점 리뷰 배지가 생기면 각 안이 어떻게 되는지도 설명하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자