大表未分區將無法發揮 Oracle 管理海量數據的優勢。分區帶來三大核心收益:
SET ECHO OFF FEED OFF VER OFF PAGES 0
SPOOL audon.sql
SELECT 'AUDIT SELECT ON '||owner||'.'||object_name||' BY ACCESS;'
FROM dba_objects
WHERE object_type IN ('TABLE','VIEW') AND owner IN ('ORDADM');
SPOOL OFF
@audon.sql
CREATE TABLE aud_summary (obj_name VARCHAR2(30), owner VARCHAR2(30), hits NUMBER);
INSERT INTO aud_summary SELECT obj_name, owner, COUNT(*) FROM dba_audit_object GROUP BY obj_name, owner;
@audoff.sql
DELETE FROM sys.aud$;
| 表名 | 行數 | 命中數 | 結論 |
|---|---|---|---|
| DOCTOR_ORDERS | 2,052,709 | 30,309 | 行數大、頻率高 → 分區 |
| ORDERS | 1,633,010 | 40,421 | |
| ORDERS_COSTS | 2,403,214 | 10,109 | |
| DRUG_STOCK | 2,511 | 11,094 | 行數小 → 不分區 |
| GROUP_ORDER_* | <4,000 | <1,200 | 行數小 → 不分區 |
重點處理 ORDERS 表(護士站執行醫囑,日增萬條,與計費緊密關聯)。
使用 ANALYZE TABLE ... ESTIMATE STATISTICS SAMPLE 20 PERCENT 收集統計信息,查詢 DBA_TAB_COLUMNS.NUM_DISTINCT:
| 候選欄位 | 不重複值 | 分布特徵 | 評估 |
|---|---|---|---|
| ORDER_CODE | 825 | 非均勻 | 不適合 |
| ORDER_CLASS | 9 | 均勻 | 可作 Hash 子分區 |
| ORDERING_DEPT | 15 | 均勻 | 可作 Hash 子分區 |
| START_DATE_TIME | 1,194,176 | 時間序列 | 最佳範圍分區鍵 |
| STOP_DATE_TIME | 636,798 | 時間序列 | 備選 |
START_DATE_TIME 每月一個分區ORDERING_DEPT 或 ORDER_CODE 每分區 3 個子分區優勢:月度統計查詢僅掃描單分區,跨月查詢並行度高,歷史分區易歸檔/刪除。
CREATE TABLE orders (
patient_id VARCHAR2(10) NOT NULL,
order_no NUMBER(4),
order_sub_no NUMBER(2),
order_class CHAR(1),
order_text VARCHAR2(80),
order_code VARCHAR2(10),
start_date_time DATE,
stop_date_time DATE,
ordering_dept VARCHAR2(8),
...
STORAGE (INITIAL 100M NEXT 1M)
)
PARTITION BY RANGE (start_date_time)
SUBPARTITION BY HASH (order_code)
SUBPARTITIONS 3 STORE IN (ordersub1, ordersub2, ordersub3)
(
PARTITION orders200212 VALUES LESS THAN (TO_DATE('2003-01-01','YYYY-MM-DD')) TABLESPACE tsp_orders,
PARTITION orders200301 VALUES LESS THAN (TO_DATE('2003-02-01','YYYY-MM-DD')) TABLESPACE tsp_orders,
PARTITION orders200302 VALUES LESS THAN (TO_DATE('2003-03-01','YYYY-MM-DD')) TABLESPACE tsp_orders,
...
PARTITION orders200402 VALUES LESS THAN (TO_DATE('2004-03-01','YYYY-MM-DD')) TABLESPACE tsp_orders
);
| 操作 | 語法範例 |
|---|---|
| 新增分區 | ALTER TABLE orders ADD PARTITION orders200403 VALUES LESS THAN (TO_DATE('2004-04-01','YYYY-MM-DD')) TABLESPACE tsp_orders; |
| 刪除分區 | ALTER TABLE orders DROP PARTITION orders200212; |
| 截斷分區 | ALTER TABLE orders TRUNCATE PARTITION orders200212; |
| 移動分區 | ALTER TABLE orders MOVE PARTITION orders200301 TABLESPACE tsp_archive; |
| 拆分分區 | ALTER TABLE orders SPLIT PARTITION orders200301 AT (TO_DATE('2003-01-16','YYYY-MM-DD')) INTO (PARTITION orders200301a, PARTITION orders200301b); |
| 合併分區 | ALTER TABLE orders MERGE PARTITIONS orders200301, orders200302 INTO PARTITION orders200301_02; |
-- 全局索引(跨分區唯一約束)
ALTER TABLE orders ADD CONSTRAINT pk_orders PRIMARY KEY (patient_id, visit_id, order_no, order_sub_no)
USING INDEX PCTFREE 5 TABLESPACE tsp_orders;
-- 本地索引(分區對齊,維護更靈活)
CREATE INDEX idx_orders_dept ON orders (ordering_dept) LOCAL;
SELECT partition_name, NUM_ROWS FROM user_tab_partitions WHERE table_name='ORDERS';
預期:各月分區行數均勻,查詢計畫顯示 PARTITION RANGE SINGLE/ITERATOR。
分區策略核心三步:審計識別熱表 → 統計分析選鍵 → 範圍+哈希組合分區。配合本地索引、分區級維護、歷史數據歸檔,可將 TB 級表查詢從分鐘級降至秒級,運維成本大幅下降。Oracle 8i+ 版本均完美支援,社保、電信、醫療等大數據場景強烈推薦。