테마
이 문제는 교재 18화 졸업 과제와 같은 이커머스 데이터베이스를 씁니다. 『튜너의 1년』을 순서대로 읽고 있다면 졸업 과제를 먼저 풀고 오세요. 아래 「테이블과 인덱스」 칸에 과제의 답 일부(제약 조건, 인덱스, 통계의 실제 상태)가 나옵니다.
이커머스 운영팀은 라이선스 점검에서 Tuning Pack을 계약하지 않았다는 것을 확인하고, 어제 저녁 CONTROL_MANAGEMENT_PACK_ACCESS를 DIAGNOSTIC+TUNING에서 DIAGNOSTIC으로 바꿨다. 에러는 하나도 나지 않았다.
오늘 아침부터 「고객 주문 내역」 API(하루 약 2만 번)의 응답이 느려졌다. 다른 API는 그대로다. 소스에는 2년 전 외주 개발자가 넣은 힌트가 있고, 작년 7월 성능 점검 기록에는 "튜닝 어드바이저 권고 1건 수용"이라는 줄이 있다.
orders: 34,908행 · 193블록 · PK(order_id)만 · 고객당 평균 6.7건order_items: 73,498행 · 290블록 · PK(order_item_id)만(order_id 인덱스 없음) · 주문당 평균 2.1줄products: 280행 · 8블록 · PK(product_id)만DBA_SQL_PROFILES: SYS_SQLPROF_0189c2f7a5d30001 · STATUS ENABLED · 작년 7월 생성SELECT /*+ LEADING(o oi) USE_NL(oi) */
o.order_id, o.order_date, o.status, oi.product_id, p.name, oi.quantity, oi.unit_price
FROM orders o, order_items oi, products p
WHERE o.customer_id = :cid
AND oi.order_id = o.order_id
AND p.product_id = oi.product_id
[오늘 아침 — 주문 7건인 고객]
-----------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
-----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 15 |00:00:00.02 | 2231 |
|* 1 | HASH JOIN | | 1 | 14 | 15 |00:00:00.02 | 2231 |
| 2 | NESTED LOOPS | | 1 | 14 | 15 |00:00:00.02 | 2223 |
|* 3 | TABLE ACCESS FULL| ORDERS | 1 | 7 | 7 |00:00:00.01 | 193 |
|* 4 | TABLE ACCESS FULL| ORDER_ITEMS | 7 | 2 | 15 |00:00:00.02 | 2030 |
| 5 | TABLE ACCESS FULL | PRODUCTS | 1 | 280 | 280 |00:00:00.01 | 8 |
-----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("P"."PRODUCT_ID"="OI"."PRODUCT_ID")
3 - filter("O"."CUSTOMER_ID"=:CID)
4 - filter("OI"."ORDER_ID"="O"."ORDER_ID")
(Note 절 없음)
[어제 — DBA_HIST_SQL_PLAN 의 같은 SQL_ID] HASH JOIN 둘 (ORDERS · ORDER_ITEMS · PRODUCTS 를 한 번씩) · 평균 491블록
Note : SQL profile "SYS_SQLPROF_0189c2f7a5d30001" used for this statement
프로파일 안의 힌트 : OPTIMIZER_FEATURES_ENABLE(default) · IGNORE_OPTIM_EMBEDDED_HINTS