테마
이 문제는 교재 18화 졸업 과제와 같은 이커머스 데이터베이스를 씁니다. 『튜너의 1년』을 순서대로 읽고 있다면 졸업 과제를 먼저 풀고 오세요. 아래 「테이블과 인덱스」 칸에 과제의 답 일부(제약 조건, 인덱스, 통계의 실제 상태)가 나옵니다.
고객센터 상담 화면의 「최근 구매 상품」 칸은 고객 번호를 넣으면 고객명과 등급, 최근 구매 상품 20줄(주문일 · 상품명 · 카테고리 · 수량 · 금액)을 보여 준다. 상담원 40명이 하루 4만 번 누른다. 18화 졸업 과제의 「주문 내역」(E1) 바로 옆 칸이다. 고객사는 "이 칸 하나를 처음부터 다시 봐 달라. 인덱스는 승인 절차(T2)를 거치면 만들 수 있다"라고 요청했다.
customers: 5,230행 · 51블록 · PK_CUSTOMERS (customer_id) · UQ(email)orders: 34,908행 · 193블록 · PK만 있음 · 고객당 평균 6.7건 · 고객 390은 16건 · order_date 시분초 있음order_items: 73,498행 · 290블록 · PK만 있음 · 주문당 평균 2.1줄 · 고객 390의 구매 줄 35개products 280행 · 8블록, categories 53행 · 4블록 (parent_id 계층) · 둘 다 PK만 있음DISABLED NOT VALIDATED · 조인 키에 인덱스 0개 · 18화에서 shipping.address_id 고아 2,719행이 나왔다 · 통계 최신SELECT c.name AS cust_name, c.grade, o.order_id, o.order_date,
p.name AS product_name, g.name AS category_name,
i.quantity, i.quantity * i.unit_price AS amount
FROM customers c, orders o, order_items i, products p, categories g
WHERE c.customer_id = :cust
AND o.customer_id = c.customer_id
AND i.order_id = o.order_id
AND p.product_id = i.product_id
AND g.category_id = p.category_id
ORDER BY o.order_date DESC
FETCH FIRST 20 ROWS ONLY
----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 20 |00:00:00.02 | 498 |
|* 1 | VIEW | | 1 | 14 | 20 |00:00:00.02 | 498 |
|* 2 | WINDOW SORT PUSHED RANK | | 1 | 14 | 20 |00:00:00.02 | 498 |
|* 3 | HASH JOIN | | 1 | 14 | 35 |00:00:00.02 | 498 |
|* 4 | HASH JOIN | | 1 | 14 | 35 |00:00:00.02 | 494 |
|* 5 | HASH JOIN | | 1 | 14 | 35 |00:00:00.02 | 486 |
| 6 | NESTED LOOPS | | 1 | 7 | 16 |00:00:00.01 | 196 |
| 7 | TABLE ACCESS BY INDEX ROWID| CUSTOMERS | 1 | 1 | 1 |00:00:00.01 | 3 |
|* 8 | INDEX UNIQUE SCAN | PK_CUSTOMERS | 1 | 1 | 1 |00:00:00.01 | 2 |
|* 9 | TABLE ACCESS FULL | ORDERS | 1 | 7 | 16 |00:00:00.01 | 193 |
| 10 | TABLE ACCESS FULL | ORDER_ITEMS | 1 | 73498 | 73498 |00:00:00.01 | 290 |
| 11 | TABLE ACCESS FULL | PRODUCTS | 1 | 280 | 280 |00:00:00.01 | 8 |
| 12 | TABLE ACCESS FULL | CATEGORIES | 1 | 53 | 53 |00:00:00.01 | 4 |
----------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("from$_subquery$_006"."rowlimit_$$_rownumber"<=20)
2 - filter(ROW_NUMBER() OVER ( ORDER BY INTERNAL_FUNCTION("O"."ORDER_DATE") DESC )<=20)
3 - access("G"."CATEGORY_ID"="P"."CATEGORY_ID")
4 - access("P"."PRODUCT_ID"="I"."PRODUCT_ID")
5 - access("I"."ORDER_ID"="O"."ORDER_ID")
8 - access("C"."CUSTOMER_ID"=:CUST)
9 - filter("O"."CUSTOMER_ID"=:CUST)