Oracle分区表 #
一、分区表概述 #
1.1 什么是分区表 #
分区表是将大表分割成多个小表的技术,每个分区可以独立管理,提高查询性能和管理效率。
text
分区优势
├── 性能提升
│ ├── 分区裁剪
│ └── 并行处理
├── 管理简化
│ ├── 独立备份
│ └── 分区维护
├── 可用性
│ └── 分区独立可用
└── 存储
└── 分区存储不同表空间
1.2 分区类型 #
text
分区类型
├── 范围分区(Range)
│ └── 按值范围分区
├── 列表分区(List)
│ └── 按离散值分区
├── 哈希分区(Hash)
│ └── 按哈希值分区
├── 复合分区(Composite)
│ └── 多级分区组合
└── 引用分区(Reference)
└── 按外键引用分区
二、范围分区 #
2.1 创建范围分区表 #
sql
-- 按日期范围分区
CREATE TABLE sales (
sale_id NUMBER,
sale_date DATE,
amount NUMBER,
region VARCHAR2(50)
)
PARTITION BY RANGE (sale_date) (
PARTITION p2023 VALUES LESS THAN (TO_DATE('2024-01-01', 'YYYY-MM-DD')),
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 pmax VALUES LESS THAN (MAXVALUE)
);
-- 按数值范围分区
CREATE TABLE orders (
order_id NUMBER,
order_date DATE,
amount NUMBER
)
PARTITION BY RANGE (amount) (
PARTITION p_small VALUES LESS THAN (1000),
PARTITION p_medium VALUES LESS THAN (10000),
PARTITION p_large VALUES LESS THAN (100000),
PARTITION p_max VALUES LESS THAN (MAXVALUE)
);
2.2 范围分区管理 #
sql
-- 添加分区
ALTER TABLE sales ADD PARTITION p2026
VALUES LESS THAN (TO_DATE('2027-01-01', 'YYYY-MM-DD'));
-- 分裂分区
ALTER TABLE sales SPLIT PARTITION pmax
AT (TO_DATE('2027-01-01', 'YYYY-MM-DD'))
INTO (PARTITION p2026, PARTITION pmax);
-- 合并分区
ALTER TABLE sales MERGE PARTITIONS p2023, p2024
INTO PARTITION p2023_2024;
-- 删除分区
ALTER TABLE sales DROP PARTITION p2023;
-- 截断分区
ALTER TABLE sales TRUNCATE PARTITION p2024;
三、列表分区 #
3.1 创建列表分区表 #
sql
-- 按地区列表分区
CREATE TABLE customers (
customer_id NUMBER,
name VARCHAR2(100),
region VARCHAR2(50)
)
PARTITION BY LIST (region) (
PARTITION p_north VALUES ('Beijing', 'Tianjin'),
PARTITION p_south VALUES ('Shanghai', 'Guangzhou'),
PARTITION p_west VALUES ('Chengdu', 'Chongqing'),
PARTITION p_other VALUES (DEFAULT)
);
-- 添加分区值
ALTER TABLE customers MODIFY PARTITION p_north
ADD VALUES ('Shenyang');
-- 删除分区值
ALTER TABLE customers MODIFY PARTITION p_north
DROP VALUES ('Shenyang');
四、哈希分区 #
4.1 创建哈希分区表 #
sql
-- 创建哈希分区表
CREATE TABLE transactions (
trans_id NUMBER,
trans_date DATE,
amount NUMBER
)
PARTITION BY HASH (trans_id)
PARTITIONS 4
STORE IN (ts1, ts2, ts3, ts4);
-- 或指定分区名
CREATE TABLE transactions (
trans_id NUMBER,
trans_date DATE,
amount NUMBER
)
PARTITION BY HASH (trans_id) (
PARTITION p1,
PARTITION p2,
PARTITION p3,
PARTITION p4
);
五、复合分区 #
5.1 创建复合分区表 #
sql
-- 范围-列表复合分区
CREATE TABLE sales_data (
sale_id NUMBER,
sale_date DATE,
region VARCHAR2(50),
amount NUMBER
)
PARTITION BY RANGE (sale_date)
SUBPARTITION BY LIST (region)
SUBPARTITION TEMPLATE (
SUBPARTITION sp_north VALUES ('Beijing', 'Tianjin'),
SUBPARTITION sp_south VALUES ('Shanghai', 'Guangzhou'),
SUBPARTITION sp_other VALUES (DEFAULT)
) (
PARTITION p2023 VALUES LESS THAN (TO_DATE('2024-01-01', 'YYYY-MM-DD')),
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'))
);
-- 范围-哈希复合分区
CREATE TABLE orders_data (
order_id NUMBER,
order_date DATE,
customer_id NUMBER,
amount NUMBER
)
PARTITION BY RANGE (order_date)
SUBPARTITION BY HASH (customer_id)
SUBPARTITIONS 4 (
PARTITION p2023 VALUES LESS THAN (TO_DATE('2024-01-01', 'YYYY-MM-DD')),
PARTITION p2024 VALUES LESS THAN (TO_DATE('2025-01-01', 'YYYY-MM-DD'))
);
六、分区索引 #
6.1 本地索引 #
sql
-- 本地索引:每个分区独立索引
CREATE INDEX idx_sales_date ON sales(sale_date) LOCAL;
-- 本地分区索引
CREATE INDEX idx_sales_local ON sales(sale_id, sale_date)
LOCAL (
PARTITION p2023,
PARTITION p2024,
PARTITION p2025,
PARTITION pmax
);
6.2 全局索引 #
sql
-- 全局索引:跨所有分区的索引
CREATE INDEX idx_sales_global ON sales(sale_id) GLOBAL;
-- 全局分区索引
CREATE INDEX idx_sales_global_part ON sales(sale_date)
GLOBAL PARTITION BY RANGE (sale_date) (
PARTITION pg1 VALUES LESS THAN (TO_DATE('2024-07-01', 'YYYY-MM-DD')),
PARTITION pg2 VALUES LESS THAN (MAXVALUE)
);
七、分区操作 #
7.1 分区查询 #
sql
-- 查询特定分区
SELECT * FROM sales PARTITION(p2024);
-- 查看分区信息
SELECT table_name, partition_name, high_value, num_rows
FROM user_tab_partitions
WHERE table_name = 'SALES';
-- 查看子分区信息
SELECT table_name, partition_name, subpartition_name
FROM user_tab_subpartitions
WHERE table_name = 'SALES_DATA';
7.2 分区维护 #
sql
-- 移动分区
ALTER TABLE sales MOVE PARTITION p2024
TABLESPACE users_new;
-- 交换分区
CREATE TABLE sales_temp AS SELECT * FROM sales WHERE 1=0;
ALTER TABLE sales EXCHANGE PARTITION p2024 WITH TABLE sales_temp;
-- 重命名分区
ALTER TABLE sales RENAME PARTITION p2024 TO p_2024;
八、分区裁剪 #
8.1 分区裁剪示例 #
sql
-- 分区裁剪:只扫描相关分区
-- 查询自动使用分区裁剪
SELECT * FROM sales
WHERE sale_date BETWEEN TO_DATE('2024-01-01', 'YYYY-MM-DD')
AND TO_DATE('2024-12-31', 'YYYY-MM-DD');
-- 只扫描p2024分区
-- 查看执行计划
EXPLAIN PLAN FOR
SELECT * FROM sales WHERE sale_date >= TO_DATE('2024-01-01', 'YYYY-MM-DD');
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
九、总结 #
分区类型选择:
| 分区类型 | 适用场景 | 分区键 |
|---|---|---|
| 范围分区 | 日期、数值范围 | 连续值 |
| 列表分区 | 地区、类别 | 离散值 |
| 哈希分区 | 均匀分布 | 任意值 |
| 复合分区 | 多维度分析 | 多列 |
最佳实践:
- 选择合适的分区键
- 定期维护分区
- 使用本地索引
- 利用分区裁剪优化查询
- 合理设置分区数量
恭喜你完成Oracle完全指南的学习!
最后更新:2026-03-27