테마
이 문제는 교재 18화 졸업 과제와 같은 이커머스 데이터베이스를 씁니다. 『튜너의 1년』을 순서대로 읽고 있다면 졸업 과제를 먼저 풀고 오세요. 아래 「테이블과 인덱스」 칸에 과제의 답 일부(제약 조건, 인덱스, 통계의 실제 상태)가 나옵니다.
고객센터 상담원은 고객이 불러 주는 이메일로 최근 30일 주문을 찾는다. 상담원 40명이 하루 1만 번쯤 누른다.
18화 T2 절차로 orders에 인덱스 두 개가 생긴 뒤에도 이 화면만은 그대로라는 민원이 올라왔다. 개발자는 "주문 화면이니 주문부터 읽게 힌트를 달았다"라고 한다. 아래는 고객 한 명(최근 30일 주문 2건)을 조회한 실행계획이다.
customers: 5,230행 · 51블록 · PK_CUSTOMERS (customer_id) · UQ_CUSTOMERS_EMAIL (email)orders: 34,908행 · 193블록 · PK_ORDERS (order_id) · IX_ORDERS_DT (order_date) · IX_ORDERS_CUST_DT (customer_id, order_date) (둘 다 18화 T2로 승인된 인덱스)SELECT /*+ LEADING(o c) USE_NL(c) */
o.order_id, o.order_date, o.status, o.total_amount
FROM orders o, customers c
WHERE c.email = :email
AND o.customer_id = c.customer_id
AND o.order_date >= :d_from
ORDER BY o.order_date DESC
------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 2 |00:00:00.01 | 611 |
| 1 | SORT ORDER BY | | 1 | 1 | 2 |00:00:00.01 | 611 |
| 2 | NESTED LOOPS | | 1 | 1 | 2 |00:00:00.01 | 611 |
| 3 | NESTED LOOPS | | 1 | 573 | 573 |00:00:00.01 | 38 |
| 4 | TABLE ACCESS BY INDEX ROWID BATCHED | ORDERS | 1 | 573 | 573 |00:00:00.01 | 10 |
|* 5 | INDEX RANGE SCAN | IX_ORDERS_DT | 1 | 573 | 573 |00:00:00.01 | 3 |
|* 6 | INDEX UNIQUE SCAN | PK_CUSTOMERS | 573 | 1 | 573 |00:00:00.01 | 28 |
|* 7 | TABLE ACCESS BY INDEX ROWID | CUSTOMERS | 573 | 1 | 2 |00:00:00.01 | 573 |
------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("O"."ORDER_DATE">=:D_FROM)
6 - access("C"."CUSTOMER_ID"="O"."CUSTOMER_ID")
7 - filter("C"."EMAIL"=:EMAIL)
Starts와 A-Rows를 비교해 이 조인이 무엇을 낭비하는지 설명하시오.