PostgreSQL 10开始,实现了原生表分区,算是真正意义上进入了支持分区的数据库的圈子。
11实现了大量的功能如支持更新分区键、默认分区、自动创建分区索引、外键支持、唯一索引、分区聚合pushdown(enable_partitionwise_aggregate
)、哈希分区、动态分区剪除,但这个版本的分区算不上真正的成熟(GA不代表mature),12才算是勉强的成熟,可以广泛用于生产。
创建分区
创建分区索引
和mysql一样,在pg实现中,只有分区本地索引,没有全局索引,但是社区已经有提案https://www.percona.com/blog/2019/11/20/proposal-for-global-indexes-in-postgresql/,主要是因为绝大部分情况下,分区数量没有成千上万的时候,全局索引搜索的效率远比搜索多个本地索引效率高,主键定义时必须包含分区键。
CREATE INDEX idx_entrus_no_f ON ses_entrust USING btree (entrust_no, init_date); -- 默认在所有分区上创建索引,如果指定了ONLY子句,则不在分区上创建索引,这样做通常无意义
查看分区定义
select
*
from
pg_partition_tree(
'traffic_violations_p'
);
relid |parentrelid|isleaf|level|
----------------|-----------|------|-----|
ses_entrust | |false | 0|
ses_entrust_1_f |ses_entrust|true | 1|
ses_entrust_2_f |ses_entrust|true | 1|
ses_entrust_3_f |ses_entrust|true | 1|
ses_entrust_4_f |ses_entrust|true | 1|
ses_entrust_5_f |ses_entrust|true | 1|
ses_entrust_6_f |ses_entrust|true | 1|
ses_entrust_7_f |ses_entrust|true | 1|
ses_entrust_8_f |ses_entrust|true | 1|
ses_entrust_9_f |ses_entrust|true | 1|
ses_entrust_10_f|ses_entrust|true | 1|
ses_entrust_11_f|ses_entrust|true | 1|
ses_entrust_12_f|ses_entrust|true | 1|
ses_entrust_13_f|ses_entrust|true | 1|
ses_entrust_14_f|ses_entrust|true | 1|
ses_entrust_15_f|ses_entrust|true | 1|
ses_entrust_16_f|ses_entrust|true | 1|
ses_entrust_17_f|ses_entrust|true | 1|
ses_entrust_18_f|ses_entrust|true | 1|
ses_entrust_19_f|ses_entrust|true | 1|
ses_entrust_20_f|ses_entrust|true | 1|
ses_entrust_21_f|ses_entrust|true | 1|
ses_entrust_22_f|ses_entrust|true | 1|
ses_entrust_23_f|ses_entrust|true | 1|
ses_entrust_24_f|ses_entrust|true | 1|
ses_entrust_25_f|ses_entrust|true | 1|
ses_entrust_26_f|ses_entrust|true | 1|
ses_entrust_27_f|ses_entrust|true | 1|
ses_entrust_28_f|ses_entrust|true | 1|
ses_entrust_29_f|ses_entrust|true | 1|
ses_entrust_30_f|ses_entrust|true | 1|
ses_entrust_31_f|ses_entrust|true | 1|
ses_entrust_32_f|ses_entrust|true | 1|
查看分区剪除(pruning)及按分区关联、聚合
讨论分区,不看分区剪除的效果就是耍流氓。最多基于11版本,因为12版本届时尚未发布,基于13测试的测试见此)。
分区对OLTP的性能影响
至少在千万级以下(30个字段、或200字节每行为界),分区意义弊大于利(可能比非分区表增加10%左右响应时间以及cost),当分区只有个位数个时,分区意义也不大。
https://www.2ndquadrant.com/en/blog/partition-elimination-postgresql-11/
分区 vs 非分区的性能 https://wenku.baidu.com/view/1a1f00da5cbfc77da26925c52cc58bd63086935e.html
哈希分区数量的建议
推荐为2的倍数。参见:http://www.manongjc.com/article/90533.html。事实上因为分区数量有限,通常成百上千最多了,所以影响有限。
组合分区与多列分区
当前,pg暂不支持子分区(组合分区)。
分区与并行
讨论分区,不和并行一起讨论是不完整的。可惜的是,在pg当前的实现中,所有Append下的子计划(subplan)间均不支持并行执行,只支持子计划内的并行执行。
其他
从pg 13开始,逻辑复制支持针对分区表。
自动创建分区