當單表數據量達到 GB 級並持續增長時,分區表成為簡化管理、提升查詢性能、實現分層存儲的關鍵技術。本文全面解析 Oracle 分區表的四大類型、三類分區索引、DDL 語法、實戰案例,並深入剖析 Oracle EBS 交易表 MTL_MATERIAL_TRANSACTIONS 的分區結構設計。
將一張邏輯大表物理劃分為多個分區,每個分區可獨立存儲於不同表空間、獨立維護、獨立備份。對應用透明,SQL 無需修改即可受益於分區剪枝。
LONG/LONG RAW 列的表不可分區CREATE TABLE range_example (
range_key_column DATE,
data VARCHAR2(20),
id INTEGER
)
PARTITION BY RANGE (range_key_column) (
PARTITION part01 VALUES LESS THAN (TO_DATE('2008-07-01','yyyy-mm-dd')) TABLESPACE tbs01,
PARTITION part02 VALUES LESS THAN (TO_DATE('2008-08-01','yyyy-mm-dd')) TABLESPACE tbs02,
PARTITION part03 VALUES LESS THAN (TO_DATE('2008-09-01','yyyy-mm-dd')) TABLESPACE tbs03
);
CREATE TABLE list_example (
dname VARCHAR2(10),
data VARCHAR2(20)
)
PARTITION BY LIST (dname) (
PARTITION part01 VALUES ('ME','PE','QC','RD'),
PARTITION part02 VALUES ('SMT','SALE')
);
CREATE TABLE hash_example (
hash_key_column DATE,
data VARCHAR2(20)
)
PARTITION BY HASH (hash_key_column) (
PARTITION part01, PARTITION part02
);
注意:新增哈希分區會觸發全表數據重新分佈,所有分區索引需 REBUILD。
CREATE TABLE range_hash_example (
range_column_key DATE,
hash_column_key INT,
data VARCHAR2(20)
)
PARTITION BY RANGE (range_column_key)
SUBPARTITION BY HASH (hash_column_key) SUBPARTITIONS 2 (
PARTITION part_1 VALUES LESS THAN (TO_DATE('2008-08-01','yyyy-mm-dd')) (
SUBPARTITION part_1_sub_1, SUBPARTITION part_1_sub_2, SUBPARTITION part_1_sub_3
),
PARTITION part_2 VALUES LESS THAN (TO_DATE('2008-09-01','yyyy-mm-dd')) (
SUBPARTITION part_2_sub_1, SUBPARTITION part_2_sub_2
)
);
UPDATE GLOBAL INDEXES |
| **全局非分區索引** | 傳統單一索引結構 | 簡單場景、小表 | 表分區變更導致索引 UNUSABLE 需重建 |
CREATE TABLESPACE bxj_emp_ts1
DATAFILE '/opt/oracle/oradata/gavinsit/bxj_emp_data01.dbf'
SIZE 32M AUTOEXTEND ON NEXT 32M MAXSIZE 2048M
EXTENT MANAGEMENT LOCAL;
CREATE TABLESPACE bxj_emp_ts2
DATAFILE '/opt/oracle/oradata/gavinsit/bxj_emp_data02.dbf'
SIZE 32M AUTOEXTEND ON NEXT 32M MAXSIZE 2048M
EXTENT MANAGEMENT LOCAL;
CREATE TABLE bxj_emp_tb (
emp_id NUMBER,
employee_name VARCHAR(50),
sex VARCHAR(10),
salary NUMBER
)
PARTITION BY LIST (sex) (
PARTITION bxj_emp_ts1 VALUES ('male') TABLESPACE bxj_emp_ts1,
PARTITION bxj_emp_ts2 VALUES ('female') TABLESPACE bxj_emp_ts2
);
WHERE sex = 'male' → 僅掃描 bxj_emp_ts1WHERE sex = 'female' → 僅掃描 bxj_emp_ts2CREATE INDEX bxj_emp_tb_localindex ON bxj_emp_tb(sex) LOCAL (
PARTITION idx_1 TABLESPACE bxj_emp_ts1,
PARTITION idx_2 TABLESPACE bxj_emp_ts2
);
CREATE INDEX bxj_emp_tb_globalindex ON bxj_emp_tb(salary)
GLOBAL PARTITION BY RANGE (salary) (
PARTITION idx_1 VALUES LESS THAN (10000) TABLESPACE bxj_emp_ts1,
PARTITION idx_2 VALUES LESS THAN (MAXVALUE) TABLESPACE bxj_emp_ts2
);
salary <= 10000 → 僅掃描 idx_1salary > 100000 → 僅掃描 idx_2MTL_MATERIAL_TRANSACTIONS 是 Oracle EBS 庫存模塊核心交易表,記錄所有物料移動,數據量極大,採用組合分區策略:
SELECT * FROM dba_tab_subpartitions
WHERE table_name = 'MTL_MATERIAL_TRANSACTIONS';
典型設計:範圍分區按事務日期(月/季) + 哈希子分區按事務類型/組織 ID,實現:
exp scott/tiger@mydb
-- 選擇 (3)Tables 模式
-- 指定導出分區:Table(T) or Partition(T:P) to be exported: emp:p_2023_q1
expdp system/password DIRECTORY=dp_dir DUMPFILE=mtl_mtxn_%U.dmp
TABLES=mtl_material_transactions PARTITION_OPTIONS=DEPARTITION
PARALLEL=4 COMPRESSION=ALL
BACKUP TABLESPACE ts_mtl_mtxn_2023_q1; -- 僅備份特定分區所在表空間
-- 新增分區
ALTER TABLE sales ADD PARTITION p_2024_q1 VALUES LESS THAN (TO_DATE('2024-04-01','yyyy-mm-dd'));
-- 合併分區
ALTER TABLE sales MERGE PARTITIONS p_2023_q1, p_2023_q2 INTO PARTITION p_2023_h1;
-- 分割分區
ALTER TABLE sales SPLIT PARTITION p_max AT (TO_DATE('2024-01-01','yyyy-mm-dd'))
INTO (PARTITION p_2024_q1, PARTITION p_max) UPDATE GLOBAL INDEXES;
-- 截取分區(清空數據保留結構)
ALTER TABLE sales TRUNCATE PARTITION p_2020_q1 DROP STORAGE;
-- 交換分區(與非分區表交換,極快)
ALTER TABLE sales EXCHANGE PARTITION p_2023_q1 WITH TABLE sales_staging
INCLUDING INDEXES WITHOUT VALIDATION;
DBMS_STATS.GATHER_TABLE_STATS(..., GRANULARITY=>'PARTITION')分區表是 Oracle 處理海量數據的利器,合理設計分區策略、索引架構與維護流程,能讓 TB 級甚至 PB 級數據系統保持線性擴展能力與亞秒級查詢響應。