Oracle分区表用于解决大数据量性能问题,单表超2GB时推荐使用。通过将数据按规则拆分至多个物理分区,降低IO竞争。分区类型包括范围分区(支持自动间隔)、列表分区、哈希分区,以及范围-哈希和范围-列表组合分区。表空间分配遵循声明大于默认原则。
使用场景 · 分区查询 · 范围分区表(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分区表主要分为四种类型:范围分区、列表分区、哈希分区以及它们的组合。下面逐一解析。
范围分区按照某个列的值域(大小区间)划分数据,例如按月份、按金额区间。这是最常用的分区方式。
以下是一个按月分区的示例:
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'))
);
此示例以inputdata列做范围分区,并指定按月自动创建新分区。初始仅有两个定义好的分区(t1_p1、t1_p2)。若插入2022-01-30的数据,因两个分区不满足,Oracle自动创建以SYS_P开头的新分区来存放。查看全部分区情况:


列表分区通过枚举方式将数据分组,例如按省份、按月份的奇偶月等:
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兜底。查看分区信息:


哈希分区对分区列进行哈希计算,数据大致均匀分布到指定数量的分区中。适用于无法提前预知数据分布的场景:
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
);
查看分区信息:


当单一分区方式不够灵活时,可将两种方式组合使用:先按范围做一级分区,再按哈希或列表做二级分区。这样既能控制大区间,又能将每个大区间内的数据进一步打散或分组。
先范围分区,再哈希子分区:
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)
);
查看分区及二级分区信息:



先范围分区,再列表子分区:
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'));
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述