语法
-- 主表 CREATE TABLE table_name (...) [ PARTITION BY { RANGE | LIST } ( {column_name | (expression) } ) ] -- 分区 CREATE TABLE table_name PARTITION OF parent_table [ ( )] FOR VALUES partition_bount_spec
创建分区表
-
创建父表,指定分区键和分区策略
CREATE TABLE log_par ( id serial, user_id int4, create_time timestamp(0) without time zone ) PARTITION BY RANGE(create_time)
-
创建分区,创建分区时指定分区表的父表和分区键的取值范围,注意分区键的范围不要有重叠,否则会报错。
CREATE TABLE log_par_his PARTITION OF log_par FOR VALUES FROM (UNBOUNDED) TO ('2020-01-01'); CREATE TABLE log_par_202001 PARTITION OF log_par FOR VALUES FROM ('2020-01-01') TO ('2020-02-01'); CREATE TABLE log_par_202002 PARTITION OF log_par FOR VALUES FROM ('2020-02-01') TO ('2020-03-01'); .....
-
在分区上创建相应索引,通常情况下分区键上的索引是必须的,非分区键的索引可根据实际应用场景选择是否创建。
CREATE INDEX idx_log_par_his_ctime ON log_par_his USING btree(create_time); CREATE INDEX idx_log_par_202001_ctime ON log_par_202001 USING btree(create_time); CREATE INDEX idx_log_par_202002_ctime ON log_par_202002 USING btree(create_time); .....
添加分区
CREATE TABLE log_par_202101 PARTITION OF log_par FOR VALUES FROM ('2021-01-01') TO ('2021-02-01'); CREATE INDEX idx_log_par_202101_ctime ON log_par_202101 USING btree(create_time);
删除分区
-
直接删分区
DROP TABLE log_par_202001
-
解绑分区
-- 解绑分区 ALTER TABLE log_par DETACH PARTITION log_par_202001; -- 挂载分区 ALTER TABLE log_par ATTACH PARTITION log_par_202001 FOR VALUES FROM ('2020-01-01') TO ('2020-02-01');
constraint_exclusion 参数
-
ON:所有表都通过约束优化查询
-
OFF:所有表都不通过约束优化查询
-
PARTITION:只有继承表和 UNION ALL 子查询通过检索约束来优化查询;
注意事项
-
当往父表插入数据时,数据会自动根据分区键路由规则插入到分区中,目前仅支持范围分区和列表分区。
-
分区表上的索引、约束需使用单独的命令创建,目前没办法一次性自动在所有分区上创建索引、约束。
-
内置分区表不支持定义(全局)主键,在分区表的分区上创建主键是可以的。
-
内置分区表的内部实现使用了继承。
-
如果 UPDATE 语句的新纪录违反当前分区键的约束则会报错,UPDATE 语句的新纪录目前不支持跨分区的情况。
-
性能方面:内置分区表根据分区键查询相比普通表性能差距较大,因为这种场景分区表的执行计划会扫描所有分区;根据分区键查询相比普通飙性能有小幅降低,而查询分区表子表性能相比普通表略有提升。