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

상품을 골라도 리뷰 관리 화면이 리뷰 1만 5천 건을 다 읽는다

기초SELECT이커머스51 / 700

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

상황 ​

이커머스 운영팀의 「리뷰 관리」 화면은 상품을 고르면 그 상품의 리뷰를, 고르지 않으면 전체 리뷰를 최신순으로 보여 준다. 운영자 열두 명이 하루 약 2천 번 열고, 대부분은 상품을 고른다. 이 화면의 조건절은 공통 조회 모듈이 만든다. 모듈은 옵션 조건마다 "NULL이 와도 안전하게" 컬럼과 바인드 양쪽에 NVL을 씌운다. 아래는 상품 하나(:p_id = 57, 리뷰 54건)를 골랐을 때다.

테이블과 인덱스 ​

  • reviews: 15,000행 · 775블록 · review_id PK · product_id(상품 280종, 상품당 34 ~ 76건, NULL 0건이지만 NOT NULL 제약은 없다) · customer_id · rating · content CLOB(화면은 앞 100자만 보여 준다) · created_at
  • 인덱스 IX_REVIEWS_PRD (product_id): 이 문제를 위해 만들어 둔 인덱스 · BLEVEL 1 · 통계 최신
  • 한 상품의 리뷰는 테이블 곳곳에 흩어져 있다

원본 SQL ​

sql
SELECT review_id, product_id, customer_id, rating, created_at,
       DBMS_LOB.SUBSTR(content, 100, 1) AS content_head
  FROM reviews
 WHERE NVL(product_id, -1) = NVL(:p_id, NVL(product_id, -1))
 ORDER BY created_at DESC

실행계획 학습용 예시 ​

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

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter(NVL("PRODUCT_ID",(-1))=NVL(:P_ID,NVL("PRODUCT_ID",(-1))))

문제 ​

  1. 상품을 골랐는데도 IX_REVIEWS_PRD를 쓰지 못하는 이유를 Predicate Information으로 설명하시오.
  2. 상품을 고르면 인덱스로, 고르지 않으면 전체를 읽도록 조건절을 고치시오. 고친 조건이 원래 조건과 같은 결과를 내는지 product_id가 NULL인 행의 관점에서 따져 설명하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자