支持二级分区
功能描述
二级分区功能,即在原有的range分区、list分区、hash分区、interval分区的基础上再次进行分区。
二级分区可以对表中的每个分区再次进行分区。分区类型有range、list、hash三种,一级与二级分区的分区类型可以任意组合。二级分区支持使用CREATE/ALTER/SELECT语法,用于二级分区的创建与增删改查。二级分区的相关信息可在系统表PG_PARTITION中获取。
语法格式
创建、修改和删除二级分区的语法格式请参考:CREATE TABLE SUBPARTITION、ALTER TABLE SUBPARTITION。用户也可以使用如下命令在vsql客户端中查询相关SQL语法的使用帮助信息。
\h create table subpartition
\h alter table subpartition
二级分区的增删改查:对二级分区表插入数据的语法与普通表的语法没有任何差别。当向二级分区表插入数据时,会根据一级分区和二级分区规则,把数据分布到匹配的二级分区中进行存储。
以下列举了部分与二级分区相关的常用SQL句式。
新增一级与二级分区:
ALTER TABLE table_name ADD partition_desc [ ( subpartition_desc [, ... ] ) ]
删除指定一级分区包括属于它的所有二级分区:
ALTER TABLE table_name DROP PARTITION { partition_name | { FOR ( value [ , … ] ) }
为指定一级分区新增二级分区:
ALTER TABLE table_name MODIFY PARTITION partition_name ADD subpartition_desc
删除指定二级分区:
ALTER TABLE table_name DROP SUBPARTITION { subpartition_name | { FOR ( value [ , … ] ) }
删除数据:
DELETE FROM table_name [ PARTITION { ( partition_name ) | { FOR ( value [ , ... ] ) } } ] [ WHERE ...] DELETE FROM table_name [ SUBPARTITION { ( partition_name ) | { FOR ( value [ , ... ] ) } } ] [ WHERE ...]
更新数据:
UPDATE table_name [ PARTITION { ( partition_name ) | { FOR ( value [ , ... ] ) } } ] SET [ WHERE ...] UPDATE table_name [ SUBPARTITION { ( partition_name ) | { FOR ( value [ , ... ] ) } } ] SET [ WHERE ...]
在指定二级分区查找数据:
SELECT ... FROM table_name SUBPARTITION (subpartition_name)
单独查询某个分区或子分区数据:
SELECT ... FROM table_name PARTITION { ( partition_name ) | FOR ( value [ , ... ] ) } SELECT ... FROM table_name SUBPARTITION { ( subpartition_name ) | {FOR ( value [, … ] ) }
当查询二级分区表的数据时(不能指定分区或子分区),如果查询条件中包含有分区键的条件,则在生成执行计划时会根据分区键条件过滤掉不符合条件的分区或子分区:
EXPLAIN SELECT ... FROM table_name WHERE ...
参数说明
table_name
表名。
partition_name
分区表的名称。
subpartition_name
二级分区表的名称。
SUBPARTITION BY [RANGE | LIST | HASH ]
根据column_name指定的字段进行二级分区,分区类型可以是RANGE、LIST、 HASH其一。
SUBPARTITION TEMPLATE ( subpartition_desc [, … ])
常规子分区模板定义语法,适用于Range/List/Hash子分区,当分区定义中没有指定子分区的定义时会根据子分区模板自动生成二级分区。
若没有提供子分区模板,同时partition_desc也不指定subpartition_desc,则将创建一个默认子分区。
hash_subpartition_by_quantity
Hash分区持有的子分区模板定义语法(也可用与子分区定义语法),指定创建N个Hash子分区,同时可选指定Hash子分区的tablespace名列表。
注意事项
interval分区不能作为二级分区。
示例
示例1:二级分区的创建,修改和删除。
1、创建一个分区表并插入数据。
create table t_part_list_range
( id number not null,
partition_key int,
subpartition_key int,
col2 varchar2(10)
)
partition by list(partition_key)
subpartition by range(subpartition_key)
(
partition t_partition_01 values (100)
(subpartition sub_1_1 values less than (10),
subpartition sub_1_2 values less than (20)
),
partition t_partition_02 values (200)
(subpartition sub_2_1 values less than (10),
subpartition sub_2_2 values less than (20)
)
);
insert into t_part_list_range values(1,100,5,'sub_1_1');
insert into t_part_list_range values(2,100,15,'sub_1_2');
insert into t_part_list_range values(3,200,5,'sub_2_1');
insert into t_part_list_range values(4,200,15,'sub_2_2');
insert into t_part_list_range values(5,200,16,'sub_2_2');
select * from t_part_list_range subpartition for (100,5);
2、新增一级与二级分区。
alter table t_part_list_range add partition t_partition_03 values (300)
( subpartition sub_3_1 values less than (10),
subpartition sub_3_2 values less than (20)
);
3、删除指定一级分区包括属于它的所有二级分区。
alter table t_part_list_range drop partition t_partition_02;
4、为指定一级分区新增二级分区。
alter table t_part_list_range modify partition t_partition_01 add subpartition sub_1_3 values less than (30);
5、删除指定二级分区。
alter table t_part_list_range drop subpartition sub_1_3;
示例2:一级分区为interval分区,二级分区为list分区,分区键类型为字符类型;创建并查看分区结果。
1、创建测试表,包含一级分区和二级分区。
CREATE TABLE t_subpartition_interval_list(
partition_key date,
subpartition_key varchar(20),
test varchar(20)
)partition by range(partition_key)
interval('12 month')
subpartition by list(subpartition_key)
(partition partition_p1 VALUES LESS THAN ('2019-01-01')
(subpartition sub_1_1 values('test1'),
subpartition sub_1_2 values('test2'),
subpartition sub_1_3 values (default)
),
partition partition_p2 VALUES LESS THAN ('2021-01-01')
(subpartition sub_2_1 values('test1'),
subpartition sub_2_2 values('test2'),
subpartition sub_2_3 values (default)
)
);
2、插入测试数据。
INSERT INTO t_subpartition_interval_list VALUES('2018-09-02','test','test1');
INSERT INTO t_subpartition_interval_list VALUES('2020-12-12','test2','test2');
INSERT INTO t_subpartition_interval_list VALUES('2022-02-02','interval','test3');
3、查询已有分区对应数据。
select * from t_subpartition_interval_list subpartition(sub_1_3);
select * from t_subpartition_interval_list subpartition(sub_2_2);
返回结果为:
partition_key | subpartition_key | test
---------------------+------------------+-------
2018-09-02 00:00:00 | test | test1
(1 row)
partition_key | subpartition_key | test
---------------------+------------------+-------
2020-12-12 00:00:00 | test2 | test2
(1 row)
4、查询表新增分区名。
select relname,parttype,partstrategy,boundaries
from pg_partition
where parentid = (select oid from pg_class where relname = 't_subpartition_interval_list')
union all
select relname,parttype,partstrategy,boundaries from pg_partition
where parentid in (
select oid from pg_partition
where parentid = (
select oid from pg_class where relname ='t_subpartition_interval_list'
)
order by relname)
order by relname;
返回结果为:
relname | parttype | partstrategy | boundaries
------------------------------+----------+--------------+-------------------------
partition_p1 | p | r | {2019-01-01}
partition_p2 | p | r | {2021-01-01}
sub_1_1 | s | l | {test1}
sub_1_2 | s | l | {test2}
sub_1_3 | s | l |
sub_2_1 | s | l | {test1}
sub_2_2 | s | l | {test2}
sub_2_3 | s | l |
sys_p1 | p | i | {"2023-01-01 00:00:00"}
sys_p1_subpartdefault1 | s | l |
t_subpartition_interval_list | r | i |
(11 rows)
5、查询新增分区对应数据。
select * from t_subpartition_interval_list subpartition(sys_p1_subpartdefault1);
返回结果为:
partition_key | subpartition_key | test
---------------------+------------------+-------
2022-02-02 00:00:00 | interval | test3
(1 row)