Greenplum分区表

2023-03-06 00:00:00 子句 分区 默认 分区表 分裂

Greenplum中分区表其目的也是用来避免扫描大表的全部内容,而分区表能够提升查询性能。分区是不会更改数据在segments之间的物理分布,而是对大表进行逻辑上的划分。
目前Greenplum只支持range分区和list分区,以及两种分区的组合分区。通过使用create table的partition by子句来创建分区表,然后就会创建一个父表和一系列子表。在内部,Greenplum会在父表和它的底层分区之间创建继承关系,类似于PostgreSQL的INHERITS子句的功能。

例子:
–创建范围分区

postgres=# CREATE TABLE t_part (id int, rank int, year int, gender 
postgres(# char(1), count int)
postgres-# DISTRIBUTED BY (id)
postgres-# PARTITION BY RANGE (year)
postgres-# ( START (2014) END (2019) EVERY (1),
postgres(# DEFAULT PARTITION extra );
NOTICE: CREATE TABLE will create partition "t_part_1_prt_extra" for table "t_part"
NOTICE: CREATE TABLE will create partition "t_part_1_prt_2" for table "t_part"
NOTICE: CREATE TABLE will create partition "t_part_1_prt_3" for table "t_part"
NOTICE: CREATE TABLE will create partition "t_part_1_prt_4" for table "t_part"
NOTICE: CREATE TABLE will create partition "t_part_1_prt_5" for table "t_part"
NOTICE: CREATE TABLE will create partition "t_part_1_prt_6" for table "t_part"
CREATE TABLE

我们可以看到创建了一系列相关的表。

postgres=# \d
List of relations
Schema | Name | Type | Owner | Storage
--------+--------------------+-------+---------+---------
public | t_part | table | gpadmin | heap
public | t_part_1_prt_2 | table | gpadmin | heap
public | t_part_1_prt_3 | table | gpadmin | heap
public | t_part_1_prt_4 | table | gpadmin | heap
public | t_part_1_prt_5 | table | gpadmin | heap
public | t_part_1_prt_6 | table | gpadmin | heap
public | t_part_1_prt_extra | table | gpadmin | heap
(7 rows)

当前的Greenplum数据库传统优化器允许列表分区带有多列(组合)分区键。一个范围分区只允许单一列作为分区键。Greenplum查询优化器不支持组合键,因此用户不能使用组合分区键。
并且在Greenplum中,表只有在创建的时候才能被指定为分区表,想要将普通表转换成分区表只有重新建一个分区表,然后将旧表数据导入新建分区表中。
另外gp中分区表的分区数-大不超过32767个。且和pg一样,一个已分区表上的主键或者唯-一约束必须包含所有的分区列。

分区表相关操作:
1、添加分区
我们可以通过alter table语句来为分区表增加分区,如:

ALTER TABLE sales ADD PARTITION 
START (date '2017-02-01') INCLUSIVE
END (date '2017-03-01') EXCLUSIVE;

需要注意:不能向一个具有默认分区的分区设计中增加分区,必须得先将默认分区split之后才能新增分区。

2、重命名分区
gp中默认的分区表的分区名的命名规则为:

<parentname>_<level>_prt_<partition_name>

修改分区表名直接使用alter table rename的方式即可,但是如果需要修改分区表的分区名不能使用这种方式:

postgres=# alter table t_part_1_prt_2 rename to t_part11;
ERROR: cannot rename partition "t_part_1_prt_2" directly
HINT: Table "t_part_1_prt_2" is a child partition of table "t_part". To rename it, use ALTER TABLE "t_part" RENAME PARTITION FOR(RANK(1))...

而是要写成:

postgres=# alter table t_part rename partition for(2014) to t_part_new1;
ALTER TABLE

3、增加默认分区
默认分区的作用是,当插入的数据不满足当前分区的条件时则都会插入到默认分区中,有点类似oracle中的maxvalue分区的概念。

ALTER TABLE sales ADD DEFAULT PARTITION other;

4、分区交换
分区交换是指用用一个表换掉一个现有的分区。

CREATE TABLE jan12 (LIKE sales) WITH (appendonly=true);
INSERT INTO jan12 SELECT * FROM sales_1_prt_1 ;
ALTER TABLE sales EXCHANGE PARTITION FOR (DATE '2012-01-01')
WITH TABLE jan12 WITHOUT VALIDATION;

其中WITHOUT VALIDATION子句使用时需要确保用于交换现有分区的表中的数据对于该分区上的约束是合法的。否则,针对分区表的查询可能会返回不正确的结果。

5、分区分裂
分裂一个分区会把一个分区划分成两个分区。用户可以使用ALTER TABLE命令分裂分区。用户只能在用户的分区层次的-底层分裂分区:只有包含数据的分区能被分裂。用户指定的分裂值会分在后一个分区中。

ALTER TABLE sales SPLIT PARTITION FOR ('2017-01-01')
AT ('2017-01-16')
INTO (PARTITION jan171to15, PARTITION jan1716to31);





本文来源:https://blog.csdn.net/weixin_39540651/article/details/104051620







相关文章