Oracle分区表基础教程:核心概念与实战入门
目录
应用场景 · 分区信息查询 · 范围分区(RANGE) · 固定区间分区 · 自动间隔分区 · 列表分区(LIST) · 哈希分区(HASH) · 组合分区(RANGE-HASH, RANGE-LIST) · 注意事项 · 附录
使用场景
面对海量数据,Oracle分区表是解决性能瓶颈的经典手段。官方建议单表超过2GB即需考虑分区策略。通过按指定规则将数据切分为多个物理存储单元(分区),每个分区可独立部署于不同表空间,显著降低应用复杂度并减少I/O争用——查询仅扫描相关分区,避免全表扫描。
分区查询
日常运维中,查看分区信息是高频操作,以下视图为必备工具:
-- 查看表分区信息,自动间隔分区会随数据插入自动创建新分区
select * from user_tab_partitions;
-- 查看分区表定义
select * from user_part_tables;
-- 查看二级分区信息
select * from user_tab_subpartitions;
-- 查询指定分区数据(t1为目标表,t1_p12为目标分区)
SELECT * FROM t1 partition(t1_p12);
Oracle分区表分为四种基础类型:范围分区、列表分区、哈希分区,以及它们的组合形式。以下逐一解析。
范围分区表(range)
范围分区依据指定列的数值区间划分数据,例如按月份或金额区间。这是最常用的一种分区方式,能有效提升查询效率。
固定值域区间的分区
先看一个按月分区的示例:
create table T1 (
id number,
p_month number,
username varchar2(50),
inputdata date,
constraint T1_id primary key (id)
)
partition by range(p_month)(
partition t1_p1 values less than (1),
partition t1_p2 values less than (2),
partition t1_p3 values less than (3),
partition t1_p4 values less than (4),
partition t1_p5 values less than (5),
partition t1_p6 values less than (6),
partition t1_p7 values less than (7),
partition t1_p8 values less than (8),
partition t1_p9 values less than (9),
partition t1_p10 values less than (10),
partition t1_p11 values less than (11),
partition t1_p12 values less than (maxvalue)
);
上述SQL将表T1的p_month列按数值划分为12个分区(即12个区间,最后一个使用maxvalue兜底)。分区详情可通过user_tab_partitions查询:
自动间隔的分区
手动管理分区繁琐,尤其时间维度场景。Oracle提供自动间隔分区(Interval Partitioning),实现分区随数据插入自动创建:
create table T2 (
id number,
p_month number,
username varchar2(50),
inputdata date,
constraint T2_id primary key (id)
)
partition by range(inputdata)
interval(NUMTOYMINTERVAL(1, 'MONTH'))
(
partition t1_p1 values less than (to_date('2022-01-01','yyyy-MM-dd')),
partition t1_p2 values less than (to_date('2022-01-15','yyyy-MM-dd'))
);
该语句以inputdate列作为范围分区键,指定按月间隔自动生成新分区。初始仅定义两个分区(t1_p1、t1_p2)。若插入2022-01-30的数据,因不满足现有分区范围,Oracle会自动创建一个以SYS_P开头的新分区。查看全部分区信息:
列表分区表(list)
列表分区通过枚举值对数据分组,例如按省份或月份奇偶性:
create table T2 (
id number,
p_month number,
username varchar2(50),
inputdata date,
constraint T2_id primary key (id)
)
partition by list(p_month)(
partition t2_hash_p1 values (1,3,5,7,9,11),
partition t2_hash_p2 values (2,4,6,8,10),
partition t2_hash_p3 values (default)
);
此例将奇数月(1,3,5,7,9,11)归入t2_hash_p1,偶数月归入t2_hash_p2,其余使用default兜底。查看分区信息:
哈希分区表(hash)
哈希分区对分区列进行哈希运算,数据均匀分布至指定数量分区。适用于无法预知数据分布的场景:
create table T2 (
id number,
p_month number,
username varchar2(50),
inputdata date,
constraint T2_id primary key (id)
)
partition by hash(p_month)(
partition t2_hash_p1,
partition t2_hash_p2
);
分区信息如下:
组合分区表(range hash, range list)
当单一分区方式无法满足需求时,可将两种方法结合:先按范围进行一级分区,再按哈希或列表进行二级分区。这样既控制大区间,又能在每个区间内进一步打散或分组数据。
range hash
范围分区作为一级,哈希子分区作为二级:
create table T2 (
id number,
p_month number,
username varchar2(50),
inputdata date,
constraint T2_id primary key (id)
)
partition by range(inputdata)
SUBPARTITION BY HASH(p_month) SUBPARTITIONS 2
(
partition t1_p1 values less than (to_date('2022-01-01','yyyy-MM-dd'))
(SUBPARTITION t1_p1_h1, SUBPARTITION t1_p1_h2),
partition t1_p2 values less than (to_date('2022-01-15','yyyy-MM-dd'))
(SUBPARTITION t1_p2_h1, SUBPARTITION t1_p2_h2)
);
查询一级分区与二级分区信息:
range list
范围分区作为一级,列表子分区作为二级:
create table T2 (
id number,
p_month number,
username varchar2(50),
inputdata date,
constraint T2_id primary key (id)
)
partition by range(inputdata)
SUBPARTITION BY list(p_month)
(
partition t1_p1 values less than (to_date('2022-01-01','yyyy-MM-dd'))
(SUBPARTITION t1_p1_h1 values(1,3,5,7,9,11),
SUBPARTITION t1_p1_h2 values(2,4,6,8,10),
SUBPARTITION t1_p1_h3 values(default)),
partition t1_p2 values less than (to_date('2022-01-15','yyyy-MM-dd'))
(SUBPARTITION t1_p2_h1 values(1,3,5,7,9,11),
SUBPARTITION t1_p2_h2 values(0,2,4,6,8,10))
);
查询一级分区与二级分区信息:
注意事项
表空间分配需遵循以下规则:
- 若未指定任何表空间,默认使用当前用户默认表空间。
- 若仅指定一级分区表空间,二级分区将继承一级的表空间。
- 若二级分区单独指定表空间,则以显式声明为准——显式设定优先级最高。
以下示例演示了表空间分配:
create table T2 (
id number,
p_month number,
username varchar2(50),
inputdata date,
constraint T2_id primary key (id)
)
partition by range(inputdata)
SUBPARTITION BY list(p_month)
(
partition t1_p1 values less than (to_date('2022-01-01','yyyy-MM-dd'))
tablespace users
(SUBPARTITION t1_p1_h1 values(1,3,5,7,9,11),
SUBPARTITION t1_p1_h2 values(2,4,6,8,10),
SUBPARTITION t1_p1_h3 values(default)),
partition t1_p2 values less than (to_date('2022-01-15','yyyy-MM-dd'))
tablespace cbpc
(SUBPARTITION t1_p2_h1 values(1,3,5,7,9,11) tablespace users,
SUBPARTITION t1_p2_h2 values(0,2,4,6,8,10))
);
查询二级分区表空间信息:
附录
附测试数据脚本供参考:
insert into T2 values (1,0,'zhangsan0',sysdate);
insert into T2 values (2,2,'zhangsan0',to_date('2022-01-10','yyyy-MM-dd'));
insert into T2 values (3,1,'zhangsan0',to_date('2022-02-10','yyyy-MM-dd'));
insert into T2 values (4,3,'zhangsan0',to_date('2022-03-10','yyyy-MM-dd'));
insert into T2 values (5,4,'zhangsan0',to_date('2022-04-10','yyyy-MM-dd'));
insert into T2 values (6,5,'zhangsan0',to_date('2022-05-10','yyyy-MM-dd'));
insert into T2 values (7,6,'zhangsan0',to_date('2022-06-10','yyyy-MM-dd'));
insert into T2 values (8,7,'zhangsan0',to_date('2022-07-10','yyyy-MM-dd'));
insert into T2 values (9,8,'zhangsan0',to_date('2022-08-10','yyyy-MM-dd'));
insert into T2 values (10,9,'zhangsan0',to_date('2022-09-10','yyyy-MM-dd'));
insert into T2 values (11,10,'zhangsan0',to_date('2022-10-10','yyyy-MM-dd'));
insert into T2 values (12,11,'zhangsan0',to_date('2022-11-10','yyyy-MM-dd'));
insert into T2 values (13,2,'zhangsan0',to_date('2022-12-10','yyyy-MM-dd'));
insert into T2 values (14,1,'zhangsan0',to_date('2022-01-10','yyyy-MM-dd'));
insert into T2 values (15,4,'zhangsan0',to_date('2022-02-10','yyyy-MM-dd'));
insert into T2 values (16,5,'zhangsan0',to_date('2022-05-10','yyyy-MM-dd'));
insert into T2 values (23,0,'zhangsan0',to_date('2022-06-10','yyyy-MM-dd'));
insert into T2 values (24,8,'zhangsan0',to_date('2022-07-10','yyyy-MM-dd'));
insert into T2 values (25,11,'zhangsan0',to_date('2022-08-10','yyyy-MM-dd'));
insert into T2 values (26,4,'zhangsan0',to_date('2022-09-10','yyyy-MM-dd'));
insert into T2 values (27,6,'zhangsan0',to_date('2022-01-09','yyyy-MM-dd'));















