테마
이 문제는 교재 18화 졸업 과제와 같은 이커머스 데이터베이스를 씁니다. 『튜너의 1년』을 순서대로 읽고 있다면 졸업 과제를 먼저 풀고 오세요. 아래 「테이블과 인덱스」 칸에 과제의 답 일부(제약 조건, 인덱스, 통계의 실제 상태)가 나옵니다.
이커머스 고객사는 개인정보 보관 기한(5년)이 지난 주문을 해마다 한꺼번에 지우려고 orders를 연도별 파티션 테이블 orders_p로 옮긴다. 칸째 들어내면 DELETE 없이 정리할 수 있다는 것이 이유다.
테이블은 만들어졌는데 PK를 만드는 문장에서 에러가 났다. 개발자는 에러 문구를 보고 order_date를 PK에 더한 문장을 다시 돌렸고, 이번에는 성공했다. 이관 검토를 맡은 강도현이 두 문장을 들고 왔다.
orders 주문: 34,908행 · 193블록 · order_id NUMBER(PK, 시퀀스로 매기고 바뀌지 않는다) · customer_id · order_date DATE(시분초 있음, 2020 ~ 2024) · status · total_amount. 연도마다 약 7,000건이다.orders_p(이관 대상, 문제 설정): orders를 PARTITION BY RANGE (order_date) 연도별 5칸(P2020 ~ P2024)과 빈 PMAX로 나눠 CTAS로 지었다. 칸마다 인덱스 높이는 2다.order_items, payments, shipping은 order_id로 주문을 찾는다. 주문 상세 화면은 주문번호만 넘긴다.CREATE TABLE orders_p
PARTITION BY RANGE (order_date)
( PARTITION P2020 VALUES LESS THAN (DATE '2021-01-01')
, PARTITION P2021 VALUES LESS THAN (DATE '2022-01-01')
, PARTITION P2022 VALUES LESS THAN (DATE '2023-01-01')
, PARTITION P2023 VALUES LESS THAN (DATE '2024-01-01')
, PARTITION P2024 VALUES LESS THAN (DATE '2025-01-01')
, PARTITION PMAX VALUES LESS THAN (MAXVALUE) )
AS SELECT * FROM orders;
ALTER TABLE orders_p ADD CONSTRAINT pk_orders_p PRIMARY KEY (order_id)
USING INDEX LOCAL;
[실행 결과]
CREATE TABLE orders_p ... Table created.
ALTER TABLE orders_p ADD CONSTRAINT pk_orders_p PRIMARY KEY (order_id) USING INDEX LOCAL
ORA-14039: partitioning columns must form a subset of key columns of a UNIQUE index
[개발자가 다음에 돌린 문장 · 성공]
ALTER TABLE orders_p ADD CONSTRAINT pk_orders_p PRIMARY KEY (order_id, order_date)
USING INDEX LOCAL;
Table altered.
[그 PK로 주문 상세 조회 · WHERE order_id = :id]
-------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Pstart | Pstop |
-------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 | 00:00:00.01 | 11 | | |
| 1 | PARTITION RANGE ALL | | 1 | 1 | 1 | 00:00:00.01 | 11 | 1 | 6 |
| 2 | TABLE ACCESS BY LOCAL INDEX ROWID | ORDERS_P | 5 | 1 | 1 | 00:00:00.01 | 11 | 1 | 6 |
|* 3 | INDEX RANGE SCAN | PK_ORDERS_P | 5 | 1 | 1 | 00:00:00.01 | 10 | 1 | 6 |
-------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("ORDER_ID"=:ID)
order_id의 유일성을 지키는 PK를 다시 작성하시오. 그 PK가 연도 칸을 지울 때 치르는 대가도 쓰시오.