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

상품 상세의 「최근 리뷰 10건」이 늦게 뜬다, 인기 상품일수록 심하다는데

기초SELECT이커머스307 / 700

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

상황 ​

상품팀: "상품 상세를 열 때마다 아래쪽 리뷰 칸이 늦게 뜬다. 인기 상품일수록 심한 것 같다." 상품 상세는 하루 약 8만 번 열린다. 화면은 상품 하나의 리뷰를 최신순으로 10건 보여 준다(리뷰 번호, 평점, 작성일, 작성 고객). 아래는 상품 100을 열었을 때의 실행계획이다.

테이블과 인덱스 ​

  • reviews: 15,000행 · 775블록(전체 스캔 757). content CLOB 때문에 행이 커서 블록당 약 19행이 들어간다. 인덱스는 PK(review_id) 하나뿐이다.
  • 상품당 리뷰는 34 ~ 76건(평균 53.6)이고, 상품 100은 57건이다. 한 상품의 리뷰는 테이블 곳곳의 블록에 흩어져 있다.
  • created_at은 DATE(시분초 있음)다. 같은 상품 안에서 created_at이 같은 리뷰는 지금 0쌍이지만, 그렇다는 제약은 없다.
  • FK는 꺼져 있고 product_id에 인덱스가 없다(18화 졸업 과제 때의 상태 그대로다). 통계는 최신이다.

원본 SQL ​

sql
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

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

xplan
------------------------------------------------------------------------------------------------------------
| 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)

문제 ​

  1. 이 화면이 한 번에 몇 블록을 읽는지 쓰고, '인기 상품일수록 느리다'는 말이 이 실행계획에서 맞는지 설명하시오.
  2. 어느 상품이든 10건만 읽고 멈추도록 인덱스와 SQL을 고치시오. 작성 시각이 같은 리뷰가 생기면 어떻게 되는지도 설명하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자