PostgreSQL 商用版本EPAS(阿里云ppas) - 分区表性能优化 (堪比pg_pathman)

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
云原生数据库 PolarDB 分布式版,标准版 2核8GB
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:

标签

PostgreSQL , EDB , ppas , epas , 分区表优化 , PG_PATHMAN


背景

PostgreSQL 在 10的版本,内置了分区表的语法,简化了以前需要写 RULE或TG+继承表功能 来实现分区表的模式。

《PostgreSQL 10.0 preview 功能增强 - 内置分区表》

《PostgreSQL 传统 hash 分区方法和性能》

但是内置分区表的性能还有改进的空间,对比了pg_pathman,性能差异是较大的,主要在plan代码这块。所以对于社区版本的用户,建议使用pg_pathman这个插件来使用分区表的功能。

《PostgreSQL 10 内置分区 vs pg_pathman perf profiling》

作为PostgreSQL的商用发行版本的PPAS,这块有非常大的性能改进。

PPAS分区表性能优化参数

edb_enable_pruning

Parameter Type: Boolean  
  
Default Value: true  
  
Range: {true | false}  
  
Minimum Scope of Effect: Per session  
  
When Value Changes Take Effect: Immediate  
  
Required Authorization to Activate: Session user  
  
When set to TRUE, edb_enable_pruning allows the query planner to early-prune partitioned tables.   
Early-pruning means that the query planner can “prune” (i.e., ignore) partitions that would   
not be searched in a query before generating query plans.   
This helps improve performance time as it eliminates the generation of query plans of   
partitions that would not be searched.  
  
Conversely, late-pruning means that the query planner prunes partitions after   
generating query plans for each partition.   
(The constraint_exclusion configuration parameter controls late-pruning.)  
  
The ability to early-prune depends upon the nature of the query in the WHERE clause.   
Early-pruning can be utilized in only simple queries with constraints of the type    
WHERE column = literal (e.g., WHERE deptno = 10).  
  
Early-pruning is not used for more complex queries such as   
WHERE column = expression (e.g., WHERE deptno = 10 + 5).  

edb_enable_pruning这个参数的功能是在生成执行计划之前,过滤掉不需要访问的对象,从而减少执行计划的开销。

注意,目前只适用于 "常量值" 的过滤。即使是immutable函数也不支持。

支持优化  
WHERE deptno = 10  
  
不支持优化  
WHERE deptno = 10 + 5  

对于不能过滤的分区,最后会在生成执行计划后,使用constraint_exclusion参数来过滤不需要访问的分区。

功能测试

创建分区表

postgres=# create table t (id int, info text) partition by range (id);  
CREATE TABLE  
  
postgres=# create table t0 PARTITION OF t for values from (0) to (100);  
CREATE TABLE  
postgres=# create table t1 PARTITION OF t for values from (100) to (200);  
CREATE TABLE  

开启edb_enable_pruning参数,关闭constraint_exclusion参数

postgres=# show edb_enable_pruning ;  
 edb_enable_pruning   
--------------------  
 on  
(1 row)  
  
postgres=# set constraint_exclusion =off;  
SET  

简单SQL,可以看到edb_enable_pruning起作用了,过滤了不需要访问的分区。

postgres=# explain select * from t where id=1;  
                        QUERY PLAN                          
----------------------------------------------------------  
 Append  (cost=0.00..25.88 rows=6 width=36)  
   ->  Seq Scan on t0  (cost=0.00..25.88 rows=6 width=36)  
         Filter: (id = 1)  
(3 rows)  

但是对于非常量,无法优化,没有起到过滤效果。

postgres=# explain select * from t where id=1+1;  
                        QUERY PLAN                          
----------------------------------------------------------  
 Append  (cost=0.00..51.75 rows=12 width=36)  
   ->  Seq Scan on t0  (cost=0.00..25.88 rows=6 width=36)  
         Filter: (id = 2)  
   ->  Seq Scan on t1  (cost=0.00..25.88 rows=6 width=36)  
         Filter: (id = 2)  
(5 rows)  

打开 constraint_exclusion 参数,它会对复杂SQL进行过滤(仅限于immutable、stable的函数和操作符。)

postgres=# set constraint_exclusion =on;  
SET  
postgres=# explain select * from t where id=1+1;  
                        QUERY PLAN                          
----------------------------------------------------------  
 Append  (cost=0.00..25.88 rows=6 width=36)  
   ->  Seq Scan on t0  (cost=0.00..25.88 rows=6 width=36)  
         Filter: (id = 2)  
(3 rows)  

将edb_enable_pruning关闭,过滤不受影响。只是没有起到优化效果。

postgres=# set edb_enable_pruning =off;  
SET  
postgres=# explain select * from t where id=1+1;  
                        QUERY PLAN                          
----------------------------------------------------------  
 Append  (cost=0.00..25.88 rows=6 width=36)  
   ->  Seq Scan on t0  (cost=0.00..25.88 rows=6 width=36)  
         Filter: (id = 2)  
(3 rows)  
  
postgres=# explain select * from t where id=1;  
                        QUERY PLAN                          
----------------------------------------------------------  
 Append  (cost=0.00..25.88 rows=6 width=36)  
   ->  Seq Scan on t0  (cost=0.00..25.88 rows=6 width=36)  
         Filter: (id = 1)  
(3 rows)  

性能测试

为了体现优化效果,加到2000个分区。

postgres=# do language plpgsql $$  
declare  
begin  
  for i in 2..2000 loop  
    execute 'create table t'||i||' PARTITION OF t for values from ('||200+i||') to ('||200+i+1||')';  
  end loop;  
end;  
$$;  
DO  

测试简单SQL(起到优化效果的SQL)

vi test.sql  
  
select * from t where id=1;  

TPS达到了100万。

pgbench -M prepared -n -r -P 1 -f ./test.sql -c 56 -j 56 -T 120  
progress: 1.0 s, 1031487.3 tps, lat 0.053 ms stddev 0.328  
progress: 2.0 s, 1098419.2 tps, lat 0.051 ms stddev 0.009  
progress: 3.0 s, 1075788.5 tps, lat 0.052 ms stddev 0.014  
progress: 4.0 s, 1090429.9 tps, lat 0.051 ms stddev 0.010  
progress: 5.0 s, 1091784.5 tps, lat 0.051 ms stddev 0.010  
progress: 6.0 s, 1084007.3 tps, lat 0.052 ms stddev 0.012  
progress: 7.0 s, 1094544.1 tps, lat 0.051 ms stddev 0.009  

测试不能优化的SQL,只能走传统的constraint_exclusion参数过滤的,性能下降到了1000多TPS

vi test.sql  
  
select * from t where id=1+1;  
pgbench -M prepared -n -r -P 1 -f ./test.sql -c 56 -j 56 -T 120  
progress: 1.0 s, 0.0 tps, lat -nan ms stddev -nan  
progress: 2.0 s, 412.2 tps, lat 247.149 ms stddev 591.770  
progress: 3.0 s, 1196.0 tps, lat 53.604 ms stddev 112.786  
progress: 4.0 s, 1198.0 tps, lat 46.672 ms stddev 5.575  

pg_pathman 的对比性能

pg_pathman实际上以前已经对比过,性能非常好。

《PostgreSQL 10 内置分区 vs pg_pathman perf profiling》

同样创建2000个分区,测试简单和不简单的查询。

postgres=# CREATE EXTENSION pg_pathman;      
CREATE EXTENSION      
      
postgres=# create table tbl_range(id int not null, info text, crt_time timestamp);      
CREATE TABLE      
      
postgres=# select create_range_partitions('tbl_range', 'id', 0, 100, 2000);      
 create_range_partitions       
-------------------------      
                    2000      
(1 row)  
  
  
postgres=# \d tbl_range  
                        Table "public.tbl_range"  
  Column  |            Type             | Collation | Nullable | Default   
----------+-----------------------------+-----------+----------+---------  
 id       | integer                     |           | not null |   
 info     | text                        |           |          |   
 crt_time | timestamp without time zone |           |          |   
Number of child tables: 2000 (Use \d+ to list them.)  

pg_pathman不依赖传统的constraint_exclusion参数,简单和不简单的SQL,都被过滤了。

postgres=# set constraint_exclusion =off;  
SET  
  
postgres=# explain select * from tbl_range where id=1;  
                            QUERY PLAN                               
-------------------------------------------------------------------  
 Append  (cost=0.00..24.12 rows=6 width=44)  
   ->  Seq Scan on tbl_range_1  (cost=0.00..24.12 rows=6 width=44)  
         Filter: (id = 1)  
(3 rows)  
  
postgres=# explain select * from tbl_range where id=1+1;  
                            QUERY PLAN                               
-------------------------------------------------------------------  
 Append  (cost=0.00..24.12 rows=6 width=44)  
   ->  Seq Scan on tbl_range_1  (cost=0.00..24.12 rows=6 width=44)  
         Filter: (id = 2)  
(3 rows)  

性能测试

pgbench -M prepared -n -r -P 1 -f ./test.sql -c 56 -j 56 -T 120  
  
  
-- 简单SQL  
  
progress: 3.0 s, 947237.9 tps, lat 0.059 ms stddev 0.010  
progress: 4.0 s, 949539.4 tps, lat 0.059 ms stddev 0.009  
progress: 5.0 s, 948459.0 tps, lat 0.059 ms stddev 0.010  
progress: 6.0 s, 947355.4 tps, lat 0.059 ms stddev 0.010  
progress: 7.0 s, 947789.2 tps, lat 0.059 ms stddev 0.010  
progress: 8.0 s, 949380.5 tps, lat 0.059 ms stddev 0.010  
progress: 9.0 s, 944190.6 tps, lat 0.059 ms stddev 0.023  
progress: 10.0 s, 947677.8 tps, lat 0.059 ms stddev 0.010  
  
-- 非简单SQL  
  
progress: 3.0 s, 951051.2 tps, lat 0.059 ms stddev 0.012  
progress: 4.0 s, 960237.6 tps, lat 0.058 ms stddev 0.010  
progress: 5.0 s, 961659.2 tps, lat 0.058 ms stddev 0.009  
progress: 6.0 s, 946538.5 tps, lat 0.059 ms stddev 0.012  
progress: 7.0 s, 956382.1 tps, lat 0.059 ms stddev 0.011  
progress: 8.0 s, 961674.0 tps, lat 0.058 ms stddev 0.009  
progress: 9.0 s, 957060.6 tps, lat 0.059 ms stddev 0.010  
progress: 10.0 s, 950707.1 tps, lat 0.059 ms stddev 0.013  
progress: 11.0 s, 955766.4 tps, lat 0.059 ms stddev 0.010  

pg_pathman对简单和非简单SQL的优化效果一样,都非常的好。

性能对比

分区特性 TPS
PPAS native分区 edb_enable_pruning=on 常量条件过滤 1031487
PPAS native分区 edb_enable_pruning=on 条件无法过滤 1196
PG pg_pathman分区 957060

小结

对于PPAS用户,建议能常量输入的,就使用常量输入,这样能够用到分区过滤的优化特性。(特别是在分区表非常多的情况下,优化效果非常明显)。

对于PG用户,使用pg_pathman作为分区组件,在分区很多的情况下,性能比native的分区好很多很多。

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
20天前
|
关系型数据库 分布式数据库 数据库
成都晨云信息技术完成阿里云PolarDB数据库产品生态集成认证
近日,成都晨云信息技术有限责任公司(以下简称晨云信息)与阿里云PolarDB PostgreSQL版数据库产品展开产品集成认证。测试结果表明,晨云信息旗下晨云-站群管理系统(V1.0)与阿里云以下产品:开源云原生数据库PolarDB PostgreSQL版(V11),完全满足产品兼容认证要求,兼容性良好,系统运行稳定。
|
26天前
|
缓存 安全 Java
阿里云数据库 SelectDB 内核 Apache Doris 2.0.6 版本正式发布
阿里云数据库 SelectDB 内核 Apache Doris 2.0.6 版本正式发布
|
1月前
|
SQL 存储 JSON
阿里云数据库 SelectDB 内核 Apache Doris 2.1.0 版本发布:开箱盲测性能大幅优化,复杂查询性能提升 100%
亲爱的社区小伙伴们,Apache Doris 2.1.0 版本已于 2024 年 3 月 8 日正式发布,新版本开箱盲测性能大幅优化,在复杂查询性能方面提升100%,新增Arrow Flight接口加速数据读取千倍,支持半结构化数据类型与分析函数。异步多表物化视图优化查询并助力仓库分层建模。引入自增列、自动分区等存储优化,提升实时写入效率。Workload Group 资源隔离强化及运行时监控功能升级,保障多负载场景下的稳定性。新版本已经上线,欢迎大家下载使用!
阿里云数据库 SelectDB 内核 Apache Doris 2.1.0 版本发布:开箱盲测性能大幅优化,复杂查询性能提升 100%
|
2月前
|
关系型数据库 分布式数据库 数据库
阿里云PolarDB登顶2024中国数据库流行榜:技术实力与开发者影响力
近日,阿里云旗下的自研云原生数据库PolarDB在2024年中国数据库流行度排行榜中夺冠,并刷新了榜单总分纪录,这一成就引起了技术圈的广泛关注。这一成就源于PolarDB在数据库技术上的突破与创新,以及对开发者和用户的实际需求的深入了解体会。那么本文就来分享一下关于数据库流行度排行榜的影响力以及对数据库选型的影响,讨论PolarDB登顶的关键因素,以及PolarDB“三层分离”新版本对开发者使用数据库的影响。
74 3
阿里云PolarDB登顶2024中国数据库流行榜:技术实力与开发者影响力
|
2月前
|
存储 监控 安全
阿里云网盘与相册问题之如何开通历史版本
阿里云网盘与相册是阿里云提供的云存储服务,用户可以安全便捷地存储和管理个人文件、照片等数据;本合集将介绍如何使用阿里云网盘和相册服务,包括文件上传、同步、分享,以及处理常见使用问题的技巧。
35 1
|
2月前
|
存储 安全 网络协议
阿里云网盘与相册问题之服务开通历史版本如何解决
阿里云网盘与相册是阿里云提供的云存储服务,用户可以安全便捷地存储和管理个人文件、照片等数据;本合集将介绍如何使用阿里云网盘和相册服务,包括文件上传、同步、分享,以及处理常见使用问题的技巧。
41 1
|
2月前
|
关系型数据库 分布式数据库 数据库
阿里云瑶池数据库训练营权益:PolarDB开发者大会主题资料开放下载!
阿里云瑶池数据库训练营权益:PolarDB开发者大会主题资料开放下载!
|
10天前
|
弹性计算 前端开发 Java
使用阿里云 mqtt serverless 版本超低成本快速实现 webscoket 长链接服务器
使用阿里云 MQTT Serverless 可轻松实现弹性伸缩的 WebSocket 服务,每日成本低至几元。适用于小程序消息推送的 MQTT P2P 模式。前端需注意安全,避免 AK 泄露,采用一机一密方案。后端通过调用 `RegisterDeviceCredential` API 发送消息。示例代码包括 JavaScript 前端连接和 Java 后端发送。
100 0
|
1月前
|
Cloud Native 关系型数据库 分布式数据库
热烈祝贺阿里云PolarDB登顶2024最新一期中国数据库流行榜
【2月更文挑战第3天】热烈祝贺阿里云PolarDB登顶2024最新一期中国数据库流行榜
|
2月前
|
Cloud Native 关系型数据库 分布式数据库
2024最新一期中国数据库流行榜公布:阿里云PolarDB登顶
PolarDB登顶国产数据库流行榜,持续引领云原生数据库创新
2024最新一期中国数据库流行榜公布:阿里云PolarDB登顶

相关产品

  • 云原生数据库 PolarDB