테마
이 문제는 교재 18화 졸업 과제와 같은 이커머스 데이터베이스를 씁니다. 『튜너의 1년』을 순서대로 읽고 있다면 졸업 과제를 먼저 풀고 오세요. 아래 「테이블과 인덱스」 칸에 과제의 답 일부(제약 조건, 인덱스, 통계의 실제 상태)가 나옵니다.
이커머스의 배송(shipping) 행은 주문할 때 한 줄로 생기고, 배송이 진행되면서 같은 줄이 채워진다. 출고 때 송장 번호와 택배사, 출고 시각이 들어가고, 배송 완료 때 완료 시각과 수령 메모가 들어간다. 배송은 보통 사흘 안에 끝난다.
고객센터 「최근 배송 목록」(최근 주문 2,000건)이 0.3초를 넘는다는 개선 요청이 왔다. 테이블은 개발 초기에 PCTFREE를 적지 않고(기본값 10) 만들었다.
shipping(문제 설정, 운영과 같은 순서로 쌓인 사본): 34,908행 · order_id와 1:1 · shipping_pk (order_id)뿐 · 이 문제에서는 tracking_no VARCHAR2(20), courier_cd VARCHAR2(3), shipped_at DATE, delivered_at DATE, recv_memo VARCHAR2(100) 칸이 더 있다. 지금 1,012블록이다.CREATE TABLE shipping (
order_id NUMBER NOT NULL,
address_id NUMBER,
status VARCHAR2(20) NOT NULL,
tracking_no VARCHAR2(20),
courier_cd VARCHAR2(3),
shipped_at DATE,
delivered_at DATE,
recv_memo VARCHAR2(100),
CONSTRAINT shipping_pk PRIMARY KEY (order_id)
); -- PCTFREE 를 적지 않았다 (기본값 10)
-- 출고 (택배사 연동)
UPDATE shipping
SET status = 'SHIPPED', tracking_no = :trk, courier_cd = :cc, shipped_at = SYSDATE
WHERE order_id = :oid;
-- 배송 완료 (택배사 연동)
UPDATE shipping
SET status = 'DELIVERED', delivered_at = :dt, recv_memo = :memo
WHERE order_id = :oid;
-- 고객센터 「최근 배송 목록」
SELECT s.order_id, s.status, s.tracking_no, s.delivered_at
FROM shipping s
WHERE s.order_id > :last_id - 2000
ORDER BY s.order_id DESC;
[고객센터 「최근 배송 목록」 — 최근 주문 2,000건]
-------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
-------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 2000 |00:00:00.31 | 2968 |
| 1 | TABLE ACCESS BY INDEX ROWID | SHIPPING | 1 | 2000 | 2000 |00:00:00.31 | 2968 |
|* 2 | INDEX RANGE SCAN DESCENDING| SHIPPING_PK | 1 | 2000 | 2000 |00:00:00.01 | 6 |
-------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("S"."ORDER_ID">:LAST_ID-2000)
table fetch continued row 1,512 (한 번 실행할 때)
[ANALYZE TABLE shipping COMPUTE STATISTICS]
NUM_ROWS 34,908 · BLOCKS 1,012 · CHAIN_CNT 26,140 (74.9%) · AVG_ROW_LEN 113 · PCT_FREE 10
[같은 SQL — 처음부터 최종 길이로 넣은 사본 (548블록 · CHAIN_CNT 0)]
Buffers 41 · table fetch continued row 0
ANALYZE 결과와 세션 통계로 설명하시오.