Oracle 分区表设计详解
Oracle 分区表设计详解
适用版本:Oracle Database 10g / 11g / 12c / 19c / 23ai 文档版本:v1.0 / 2026-07
1. 概述
分区表将大表分解为更小、可管理的部分[1]:
优势:
- 性能(分区裁剪)
- 管理(独立操作)
- 可用性(部分故障)
- 维护(归档)
详细见:Oracle 分区表设计。
2. 分区类型
2.1 Range
CREATE TABLE sales (
id NUMBER,
sale_date DATE,
amount NUMBER
)
PARTITION BY RANGE (sale_date) (
PARTITION p2024 VALUES LESS THAN (TO_DATE('2025-01-01', 'YYYY-MM-DD')),
PARTITION p2025 VALUES LESS THAN (TO_DATE('2026-01-01', 'YYYY-MM-DD')),
PARTITION p2026 VALUES LESS THAN (TO_DATE('2027-01-01', 'YYYY-MM-DD')),
PARTITION pmax VALUES LESS THAN (MAXVALUE)
);
2.2 List
CREATE TABLE customers (
id NUMBER,
region VARCHAR2(20)
)
PARTITION BY LIST (region) (
PARTITION p_east VALUES ('NY', 'Boston', 'Miami'),
PARTITION p_west VALUES ('LA', 'SF', 'Seattle'),
PARTITION p_central VALUES ('Chicago', 'Dallas'),
PARTITION p_other VALUES (DEFAULT)
);
2.3 Hash
CREATE TABLE orders (
id NUMBER,
customer_id NUMBER
)
PARTITION BY HASH (customer_id) PARTITIONS 8;
2.4 Composite
CREATE TABLE sales (
id NUMBER,
sale_date DATE,
region VARCHAR2(20)
)
PARTITION BY RANGE (sale_date)
SUBPARTITION BY LIST (region)
SUBPARTITION TEMPLATE (
SUBPARTITION east VALUES ('NY', 'Boston'),
SUBPARTITION west VALUES ('LA', 'SF'),
SUBPARTITION other VALUES (DEFAULT)
) (
PARTITION p2024 VALUES LESS THAN (TO_DATE('2025-01-01', 'YYYY-MM-DD')),
PARTITION p2025 VALUES LESS THAN (TO_DATE('2026-01-01', 'YYYY-MM-DD'))
);
2.5 Interval(11g+)
CREATE TABLE sales (
id NUMBER,
sale_date DATE,
amount NUMBER
)
PARTITION BY RANGE (sale_date)
INTERVAL 'NUMTOYMINTERVAL(1, ''MONTH'')' (
PARTITION p0 VALUES LESS THAN (TO_DATE('2025-01-01', 'YYYY-MM-DD'))
);
2.6 Reference
CREATE TABLE orders (
order_id NUMBER PRIMARY KEY,
customer_id NUMBER,
order_date DATE
)
PARTITION BY HASH (customer_id) PARTITIONS 4;
CREATE TABLE order_items (
item_id NUMBER,
order_id NUMBER,
product_id NUMBER,
CONSTRAINT fk_oi_order FOREIGN KEY (order_id) REFERENCES orders
)
PARTITION BY REFERENCE (fk_oi_order);
2.7 System
CREATE TABLE t (id NUMBER, name VARCHAR2(100))
PARTITION BY SYSTEM (
PARTITION p1 TABLESPACE users,
PARTITION p2 TABLESPACE users
);
INSERT INTO t PARTITION (p1) VALUES (1, 'A');
3. 选择策略
3.1 时间
- Range(日期)
- Interval(自动)
- DW / 日志
3.2 区域
- List
- 业务隔离
3.3 均匀
- Hash
- 任意列
- 负载均衡
3.4 多维
- Composite
- Range + List / Hash
4. 分区键
4.1 原则
- 查询常用
- 等值 / 范围
- 高基数(Hash)
4.2 限制
- 单列或多列
- 不能是 LONG
- 不能是 ROWID
- 限制类型
5. 索引
5.1 本地索引
CREATE INDEX idx_sales_date ON sales(sale_date) LOCAL;
5.2 全局索引
CREATE INDEX idx_sales_cust ON sales(customer_id) GLOBAL;
5.3 全局分区
CREATE INDEX idx_sales_cust ON sales(customer_id) GLOBAL
PARTITION BY HASH (customer_id) PARTITIONS 4;
详细见:Oracle 索引类型与应用。
6. 操作
6.1 添加分区
ALTER TABLE sales ADD PARTITION p2027 VALUES LESS THAN (TO_DATE('2028-01-01', 'YYYY-MM-DD'));
6.2 删除分区
ALTER TABLE sales DROP PARTITION p2024;
6.3 截断
ALTER TABLE sales TRUNCATE PARTITION p2024;
6.4 合并
ALTER TABLE sales MERGE PARTITIONS p2024, p2025 INTO PARTITION p2024_2025;
6.5 拆分
ALTER TABLE sales SPLIT PARTITION pmax AT (TO_DATE('2028-01-01', 'YYYY-MM-DD'))
INTO (PARTITION p2027, PARTITION pmax);
6.6 交换
-- 分区 ↔ 表
CREATE TABLE sales_2024 AS SELECT * FROM sales WHERE 1=0;
ALTER TABLE sales EXCHANGE PARTITION p2024 WITH TABLE sales_2024;
6.7 移动
ALTER TABLE sales MOVE PARTITION p2024 TABLESPACE users COMPRESS;
6.8 重命名
ALTER TABLE sales RENAME PARTITION p2024 TO p_old;
7. 分区裁剪
7.1 静态
SELECT * FROM sales WHERE sale_date = DATE '2025-07-21';
-- 仅扫 p2025
7.2 动态
SELECT * FROM sales WHERE sale_date = :date;
-- 运行时裁剪
7.3 验证
EXPLAIN PLAN FOR SELECT ...;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY));
-- PARTITION RANGE SINGLE
8. 智能分区连接
8.1 Partition Wise Join
SELECT * FROM sales s, customers c
WHERE s.customer_id = c.id;
-- 分区并行
9. 维护
9.1 统计
EXEC DBMS_STATS.GATHER_TABLE_STATS('SCOTT', 'SALES', cascade => TRUE);
-- 分区级
EXEC DBMS_STATS.GATHER_TABLE_STATS('SCOTT', 'SALES',
partname => 'P2025', cascade => TRUE);
-- 增量
EXEC DBMS_STATS.SET_TABLE_PREFS('SCOTT', 'SALES',
'INCREMENTAL', 'TRUE');
9.2 备份
RMAN> BACKUP TABLESPACE users;
RMAN> BACKUP DATAFILE 5;
9.3 归档
-- 旧分区归档
ALTER TABLE sales EXCHANGE PARTITION p2020 WITH TABLE sales_2020_archive;
ALTER TABLE sales DROP PARTITION p2020;
详细见:Oracle 备份策略与最佳实践。
10. 12c 新特性
10.1 Interval-Reference
-- 不支持
10.2 多列分区
PARTITION BY RANGE (a, b)
10.3 Partial Index
CREATE TABLE sales (...) PARTITION BY RANGE (sale_date) (
PARTITION p2024 ... INDEXING OFF,
PARTITION p2025 ... INDEXING ON
);
CREATE INDEX idx ON sales (...) LOCAL INDEXING PARTIAL;
10.4 Online
ALTER TABLE sales MOVE PARTITION p2024 ONLINE;
11. 查看
11.1 表
SELECT table_name, partitioning_type, partition_count
FROM user_part_tables;
11.2 分区
SELECT table_name, partition_name, tablespace_name, num_rows
FROM user_tab_partitions;
11.3 子分区
SELECT * FROM user_tab_subpartitions;
11.4 键
SELECT name, column_name, column_position FROM user_part_key_columns;
12. 性能
12.1 分区裁剪
- WHERE 分区键
- 减少扫描
12.2 并行
ALTER TABLE sales PARALLEL 4;
SELECT /*+ PARALLEL(s 4) */ * FROM sales s WHERE ...;
12.3 索引
- 本地索引优先
- 维护成本低
13. 常见坑与排错
13.1 全局索引失效
ALTER TABLE sales DROP PARTITION p2024;
-- 全局索引失效
ALTER INDEX idx_sales_cust REBUILD;
-- 或 UPDATE INDEXES
ALTER TABLE sales DROP PARTITION p2024 UPDATE INDEXES;
13.2 分区键选择不当
- 无裁剪
- 性能差
- 重新选择
13.3 分区数过多
- 管理
- 限制
- 数量合理
14. 最佳实践
- 大表分区:> 10GB
- 时间分区:Range / Interval
- Hash 均匀:负载
- 本地索引:维护
- 分区裁剪:查询
- 增量统计:性能
- 归档:空间
- Online 操作:业务
- Partial Index:12c+
- 监控:使用
15. 参考资料
[1] Oracle Database Administrator’s Guide 19c, “Partitioning” https://docs.oracle.com/en/database/oracle/oracle-database/19/vldbg/