首页 > 数据库 >9.x - 13.0 postgresql 分区表新特性及简单用法

9.x - 13.0 postgresql 分区表新特性及简单用法

时间:2023-04-18 13:35:51浏览次数:46  
标签:postgresql CREATE 分区表 pg tab time create 13.0


一、 分区表定义与意义

1. 分区表的定义

把一个大的物理表分成若干个小物理表,并使得这些小物理表在逻辑上可以被当成一张表来使用。

  • 主表/父表/Master Table

主表是创建子表的模板,是一个正常的普通表,一般主表并不存任何数据。

  • 子表/分区表/Chlid Table/Partition Table

子表继承并属于一个主表,与主表是一对多的关系,子表中存储所有的数据
 

2. 分区表的意义

  • 性能提升:特定场景,查询更新转为分区操作提升性能
• 配置表:数据量小,易管理与优化
• 状态表:数据量大,性能问题
• 流水表:有明显的时间变化,每天数据量都很大,定期归档
• 统计表:加载后数据不变,数据量很大,需统计分析
  • 历史数据:历史数据归档和清理,通过drop分区实现,非常高效
  • 存储拆分:单个表只能在一个位置,分区表冷热分离

3. 分区字段和分区策略

  • 范围分区
  • 列表分区
  • 哈希分区

二、 pg各版本分区表实现

9.x - 13.0 postgresql 分区表新特性及简单用法_分区表

1. pg官方分区表的演进

  • postgresql 9.x - 通过trigger实现的复杂传统分区表
  • postgresql 10 - 开始支持内置分区表
  • postgresql 11 - 主要完善分区表功能
  • postgresql 12 - 分区表性能提升
  • postgresql 13 - 提升性能及完善复制功能
  • postgresql 14 - 提升性能及实现部分操作非阻塞执行

2. 传统分区表 – pg 9.x及之前版本

主表和分区表需分别创建,各自定义,数据不能自动关联

主表和分区表关系:通过继承和触发器实现

创建步骤:

  • 定义父表及索引
CREATE TABLE pg_9_tab( id serial,uid int4,username varchar,create_time bigint);
CREATE INDEX idx_pg_9_tab_ctime ON pg_9_tab USING btree (create_time);
  • 定义子表及子表约束: 用 inherits 创建分区表,子表约束数据对应分区的规则
CREATE TABLE pg_9_tab_p_hisotry(CHECK ( create_time < 1569859200 ) ) INHERITS(pg_9_tab);
CREATE TABLE pg_9_tab_p_201910(CHECK ( create_time >= 1569859200 and create_time < 1572537600 ) ) INHERITS(pg_9_tab);
CREATE TABLE pg_9_tab_p_201911(CHECK ( create_time >= 1572537600 and create_time < 1575129600 ) ) INHERITS(pg_9_tab);
CREATE TABLE pg_9_tab_p_201912(CHECK ( create_time >= 1575129600 and create_time < 1577808000 ) ) INHERITS(pg_9_tab);
  • 创建子表索引 :子表不会继承父表的索引
CREATE INDEX idx_pg_9_tab_p_hisotry_ctime ON pg_9_tab_p_hisotry USING btree (create_time);
CREATE INDEX idx_pg_9_tab_p_201910_ctime ON pg_9_tab_p_201910 USING btree (create_time);
CREATE INDEX idx_pg_9_tab_p_201911_ctime ON pg_9_tab_p_201911 USING btree (create_time);
CREATE INDEX idx_pg_9_tab_p_201912_ctime ON pg_9_tab_p_201912 USING btree (create_time);
  • 创建分区插入、修改、删除函数和触发器
CREATE OR REPLACE FUNCTION pg_9_tab_insert_trigger()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
BEGIN
… …
END;
$function$;

CREATE TRIGGER insert_pg_9_tab_trigger BEFORE INSERT ON pg_9_tab FOR EACH ROW EXECUTE PROCEDURE pg_9_tab_insert_trigger();
  • 启用分区查询参数:设置 constraint_exclusion 参数
set constraint_exclusion = partition;
show constraint_exclusion;

9.x - 13.0 postgresql 分区表新特性及简单用法_分区表_02

3. 内置分区表 – pg 10 支持版本

Postgresql 10提供了内置分区表,不需要预先在父表上定义触发器,对父表的DML操作也会自动路由到相应分区。

仅支持范围分区和列表分区。

创建步骤:

  • 创建主表:指定分区键和分区策略(不能直接在主表建索引)
CREATE TABLE pg_10_tab( id serial, uid int4, username varchar, create_time bigint ) PARTITION BY RANGE(create_time);
  • 创建分区表:指定分区表的主表和分区键的取值范围,范围不能有重叠
CREATE TABLE pg_10_tab_p_hisotry PARTITION OF pg_10_tab FOR VAlUES FROM (1546272000) TO (1569859200);
CREATE TABLE pg_10_tab_p_201910 PARTITION OF pg_10_tab FOR VAlUES FROM (1569859200) TO (1572537600);
CREATE TABLE pg_10_tab_p_201911 PARTITION OF pg_10_tab FOR VAlUES FROM (1572537600) TO (1575129600);
CREATE TABLE pg_10_tab_p_201912 PARTITION OF pg_10_tab FOR VAlUES FROM (1575129600) TO (1577808000);
  • 在分区表上创建索引:分区键一般必须创建索引,其他列根据实际场景选择是否场景索引
CREATE INDEX idx_pg_10_tab_p_hisotry_ctime ON pg_10_tab_p_hisotry USING btree (create_time);
CREATE INDEX idx_pg_10_tab_p_201910_ctime ON pg_10_tab_p_201910 USING btree (create_time);
CREATE INDEX idx_pg_10_tab_p_201911_ctime ON pg_10_tab_p_201911 USING btree (create_time);
CREATE INDEX idx_pg_10_tab_p_201912_ctime ON pg_10_tab_p_201912 USING btree (create_time);
  • 插入数据及插入结果查询
INSERT INTO pg_10_tab(uid,username,create_time) SELECT round(1000*random()),chr(int4(random()*26)+65),generate_series(1568476800,1576339200,360);

SELECT count(*) FROM pg_10_tab;
SELECT count(*) FROM ONLY pg_10_tab;

\dt+ pg_10_tab*

9.x - 13.0 postgresql 分区表新特性及简单用法_数据库_03

9.x - 13.0 postgresql 分区表新特性及简单用法_postgresql_04

4. 增强分区表 – pg 11 支持版本

功能增强:

  • 分区表可以继承主表的字段、索引信息
  • 支持hash分区,rang/list 支持默认分区,多级分区
  • 分区索引增强,分区主表可以创建主键,可以创建外键,
  • DML增强,可以分区间移动行,可以路由到外部分区,

性能方面:

  • 数据搜索访问优化,提升分区检索性能

创建步骤:

  • 创建主表及相关索引:指定分区键和分区策略
CREATE TABLE pg_11_tab( id serial, uid int4, username varchar, create_time bigint ) PARTITION BY RANGE(create_time);
CREATE INDEX idx_pg_11_tab_ctime ON pg_11_tab USING btree (create_time);
  • 创建分区表:指定分区表的主表和分区键的取值范围,范围不能有重叠
CREATE TABLE pg_11_tab_p_hisotry PARTITION OF pg_11_tab DEFAULT;
CREATE TABLE pg_11_tab_p_201910 PARTITION OF pg_11_tab FOR VAlUES FROM (1569859200) TO (1572537600);
CREATE TABLE pg_11_tab_p_201911 PARTITION OF pg_11_tab FOR VAlUES FROM (1572537600) TO (1575129600);
CREATE TABLE pg_11_tab_p_201912 PARTITION OF pg_11_tab FOR VAlUES FROM (1575129600) TO (1577808000);

CREATE INDEX idx_pg_11_tab_p_hisotry_ctime ON pg_11_tab_p_hisotry USING btree (create_time); ##不用执行
CREATE INDEX idx_pg_11_tab_p_201910_ctime ON pg_11_tab_p_201910 USING btree (create_time);
CREATE INDEX idx_pg_11_tab_p_201911_ctime ON pg_11_tab_p_201911 USING btree (create_time);
CREATE INDEX idx_pg_11_tab_p_201912_ctime ON pg_11_tab_p_201912 USING btree (create_time); ##不用执行
  • 插入数据及插入结果查询
INSERT INTO pg_11_tab(uid,username,create_time) SELECT round(1000*random()),chr(int4(random()*26)+65),generate_series( 1568476800, 1576339200, 360);

SELECT count(*) FROM pg_11_tab;
SELECT count(*) FROM ONLY pg_11_tab;
\dt+ pg_11_tab*

9.x - 13.0 postgresql 分区表新特性及简单用法_数据_05

9.x - 13.0 postgresql 分区表新特性及简单用法_postgresql_06

5. 高性能分区表 – pg 12 支持版本

  • 功能方面:增加更多查询函数,便于快速查看分区表状态
  • 性能方面:分区表的性能得到大幅提升,尤其是在分区表数量非常多时,DML性能提升更加明显

创建步骤:

CREATE TABLE pg_12_tab( id serial, uid int4, username varchar, create_time bigint ) PARTITION BY RANGE(create_time);
CREATE INDEX idx_pg_12_tab_ctime ON pg_11_tab USING btree (create_time);

CREATE TABLE pg_12_tab_p_hisotry PARTITION OF pg_12_tab DEFAULT;
CREATE TABLE pg_12_tab_p_201910 PARTITION OF pg_12_tab FOR VAlUES FROM (1569859200) TO (1572537600);
CREATE TABLE pg_12_tab_p_201911 PARTITION OF pg_12_tab FOR VAlUES FROM (1572537600) TO (1575129600);
CREATE TABLE pg_12_tab_p_201912 PARTITION OF pg_12_tab FOR VAlUES FROM (1575129600) TO (1577808000);

INSERT INTO pg_12_tab(uid,username,create_time)
SELECT round(1000*random()),chr(int4(random()*26)+65),generate_series( 1568476800, 1576339200, 360);
SELECT count(*) FROM pg_12_tab;
SELECT count(*) FROM ONLY pg_12_tab;
\dt+ pg_12_tab*


9.x - 13.0 postgresql 分区表新特性及简单用法_postgresql_07

9.x - 13.0 postgresql 分区表新特性及简单用法_postgresql_08

9.x - 13.0 postgresql 分区表新特性及简单用法_postgresql_09

6. pg 13分区新特性

  • 增强分区裁剪功能,可使用场景增多
  • 增强智能分区join(partitionwise joins)
  • 支持对分区表创建before row trigger(但不允许改变插入数据的目标分区)
  • 之前只能把分区表的各个分区单独做为复制源,现在可以把分区表直接做为复制源。
  • 先前订阅者只能把数据同步到非分区表,现在可以把数据同步到分区表
  • 支持异构分区表逻辑复制: http://www.postgres.cn/v2/news/viewone/1/604
  • Allow whole-row variables (that is, table.*) to be used in partitioning expressions (Amit Langote)

案例参考: https://mp.weixin.qq.com/s/MbkdarHRrVGm3faiN7SOpw

PostgreSQL: Documentation: 13: E.5. Release 13

7. pg 14分区新特性

  • 更新和删除可以定位到更精细的分区,性能提高,节省内存
  • Autovacuum现在支持analyze分区表,并将行统计信息反馈到父表,另外可以通过调整maintenance_io_concurrency异步IO参数调优。
  • 支持非阻塞的ALTER TABLE ... DETACH PARTITION ... CONCURRENTLY
  • 所有分区子表支持 reindex,pg 14还新增了pg_amcheck工具用于检查数据是否损坏

三、 分区表实践与问题(2019.11)

1. 分区后性能降低问题

  • 业务表修改为分区表后,查询不走分区键,性能会下降很多
  • 所有的查询都需要包含分区键,分区键兼顾性能与归档
  • 如果表不是非常大,使用分区表性能降低太多,可不用分区表

2. 数据传输问题

  • 开发数据同步传输通道
  • DTS数据同步,不同版本传输性能的不同

3. 使用规范问题

  • 所有有关pg的操作,都建立在pg体系结构之上
  • 按照pg的设计和特点来使用pg

参考

《斗鱼 PostgreSQL分区表实践与思考_zhaofx_v1.5_20191122》

PostgreSQL表分区演进

关于分区表的方方面面

标签:postgresql,CREATE,分区表,pg,tab,time,create,13.0
From: https://blog.51cto.com/u_13631369/6203179

相关文章

  • MBR分区表简介
    一、主引导扇区的组成一般而言,磁道0中的第1个扇区是主引导扇区,在PC上BIOS会读取该扇区,并将控制权转交给这个扇区上的MBR(很多教材中以MBR指代主引导扇区,需要根据上下文区分)。主引导扇区由三个部分组成:主引导记录(MBR,MasterBootRecord)硬盘分区表(DPT,DiskPartitionTable)引导记录标志......
  • postgresql -- 执行计划
    一、显示执行计划pg中explain命令格式如下explain[options]sql语句例如explainselect*fromtest;explain(formatxml)select*fromtest;explain(analyzetrue,bufferstrue)select*fromtest;options可选项如下:ANALYZE(默认FALSE):实际执行sql,显示真实的执行计划及......
  • Oracle 利用在线重定义进行分区表转换
    例如原始非分区表为createtableTESTUSER.LOG_TEST("id"CHAR(36)primarykey,"created_at"DATE)一、选择重定义方法   Bykey,选择主键或者所有字段有NOTNULL约束的唯一键用于在线重定义操作。使用这种方法,在线重定义之前和之后表应该有相同的主键字段(默......
  • postgresql 函数错误捕捉
    CREATEORREPLACEFUNCTION"public"."proc_net_agent_diamond_loss"("dwuserid"int4,"strdate"date)RETURNS"public"."my_returninfo"AS$BODY$DECLAREresultMy_ReturnInfo;v_start_timeTIMESTAMP(......
  • PG技术大讲堂 - 第14讲:PostgreSQL 检查点
     PostgreSQL从小白到专家,是从入门逐渐能力提升的一个系列教程,内容包括对PG基础的认知、包括安装使用、包括角色权限、包括维护管理、、等内容,希望对热爱PG、学习PG的同学们有帮助,欢迎持续关注CUUGPG技术大讲堂。Part14:PostgreSQL检查点内容1:检查点触发机制内容2:检查点作用......
  • PG技术大讲堂 - 第13讲:PostgreSQL Full-Page Writes 全页写
     PostgreSQL从小白到专家,是从入门逐渐能力提升的一个系列教程,内容包括对PG基础的认知、包括安装使用、包括角色权限、包括维护管理、、等内容,希望对热爱PG、学习PG的同学们有帮助,欢迎持续关注CUUGPG技术大讲堂。Part13:full-pageWrites内容1:PostgreSQL全页写概述内容2:Post......
  • PostgreSQL 备忘清单_开发速查表分享
    PostgreSQL备忘清单PostgreSQL是一种特性非常齐全的自由软件的对象-关系型数据库管理系统(ORDBMS),是以加州大学计算机系开发的POSTGRES,4.2版本为基础的对象关系型数据库管理系统。POSTGRES的许多领先概念只是在比较迟的时候才出现在商业网站数据库中。PostgreSQL支持大部分的SQL标......
  • 52 openEuler搭建PostgreSQL数据库服务器-管理数据库角色
    52openEuler搭建PostgreSQL数据库服务器-管理数据库角色52.1创建角色可以使用CREATEROLE语句或createuser来创建角色。createuser是对CREATEROLE命令的封装,需要在shell界面执行,而不是在数据库界面。CREATEROLErolename[[WITH]option[...]];createuserrolename......
  • Linux 上 定时备份 postgresql 数据库
    Linux上定时备份postgresql数据库为了避免操作数据库的风险因此计划每天对postgresql数据库进行定时备份1.服务器地址:备份服务器地址10.10.10.101(虚构)postgresql数据库所在的服务器地址10.10.10.100(虚构)因为我有单独的备份数据库不在同一个服务器上操作首先要保证这......
  • 51 openEuler搭建PostgreSQL数据库服务器-安装、运行和卸载
    51openEuler搭建PostgreSQL数据库服务器-安装、运行和卸载51.1安装配置本地yum源,详细信息请参考《openEuler22.03-LTS搭建repo服务器》清除缓存。#dnfcleanall例如示例命令如下:[root@superman-21~]#dnfcleanall36filesremoved[root@superman-21~]#......