Oracle分区表基础教程:核心概念与实战入门

2026-06-16阅读 0热度 0
大数据

目录

应用场景 · 分区信息查询 · 范围分区(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'));
免责声明

本网站新闻资讯均来自公开渠道,力求准确但不保证绝对无误,内容观点仅代表作者本人,与本站无关。若涉及侵权,请联系我们处理。本站保留对声明的修改权,最终解释权归本站所有。

相关阅读

更多
欢迎回来 登录或注册后,可保存提示词和历史记录
登录后可同步收藏、历史记录和常用模板
注册即表示同意服务条款与隐私政策