Skip to content
튜닝 연습인덱스 스캔 효율과 테이블 액세스
ACC-033

리스크 모니터가 상품마다 대량 구매 서너 건을 찾는데 주문상품을 170블록씩 읽는다

기초SELECT이커머스108 / 700

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

상황 ​

리스크팀의 「대량 구매 모니터」는 5분마다 상품 280개를 차례로 돌며, 한 번에 10개 이상 산 주문상품 줄을 찾는다. 재판매 업자를 걸러 내려는 것이다. 상품 하나에 한 번씩이니 하루 약 8만 번 실행된다. 상품 상세 화면용으로 만든 product_id 인덱스를 타는데, 상품 하나에서 서너 줄을 찾는 데 170블록 넘게 읽는다. 아래는 상품 57이다.

테이블과 인덱스 ​

  • order_items 주문상품: 73,498행 · 290블록(블록당 약 253행) · order_item_id 순으로 쌓였다(주문이 들어온 순서) · 한 상품의 줄은 테이블 전체에 흩어져 있다
  • product_id 280종(상품당 약 262줄) · 이 문제에서는 quantity가 대부분 1 ~ 5이고 10개 이상은 약 1%라고 둔다
  • 상품 57: 262줄이 172블록에 흩어져 있다 · 그중 quantity >= 10은 3줄
  • 인덱스 IX_OI_PROD (product_id): 상품 상세 화면용 · BLEVEL 1 · 리프 약 160 · CLUSTERING_FACTOR 약 72,000 · 통계 최신 · 주문이 들어올 때마다 주문상품이 INSERT된다

원본 SQL ​

sql
SELECT order_item_id, order_id, quantity, unit_price
  FROM order_items
 WHERE product_id = :p
   AND quantity  >= 10

실행계획 학습용 예시 · quantity 분포는 문제에 적은 가정 ​

xplan
---------------------------------------------------------------------------------------------------------------
| Id  | Operation                            | Name          | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
---------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                     |               |      1 |        |      3 |00:00:00.01 |     174 |
|*  1 |  TABLE ACCESS BY INDEX ROWID BATCHED | ORDER_ITEMS   |      1 |      3 |      3 |00:00:00.01 |     174 |
|*  2 |   INDEX RANGE SCAN                   | IX_OI_PROD    |      1 |    262 |    262 |00:00:00.01 |       2 |
---------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("QUANTITY">=10)
   2 - access("PRODUCT_ID"=:P)

문제 ​

  1. 3줄을 찾는데 테이블을 172블록 읽는 이유를 Predicate Information의 1번과 2번 줄로 설명하시오.
  2. 테이블에 가는 횟수가 결과 건수만큼으로 줄도록 인덱스를 고치고 DDL을 작성하시오. 기존 인덱스를 어떻게 할지와 그 대가도 설명하시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자