PostgreSQL17优化器改进(5)GROUP BY优化

PostgreSQL17优化器改进(5)GROUP BY优化

我们知道GROUP BY聚集有两种常见实现方式,一种是基于哈希表,我们称为哈希聚集(Hash agg);另一种则要求先对元组进行排序,我们称为分组聚集(Group Agg)。本次在PostgreSQL17版本中描述的根据索引或order by排序来优化GROUP BY列的排序,同时新增了enable_group_by_reordering参数进行控制,默认值为on,这里GROUP BY优化其实就是对分组聚集实现方式的优化。

创建测试用例表

CREATE TABLE btg AS SELECT
  i % 100 AS x,
  i % 100 AS y,
  'abc' || i % 10 AS z,
  i AS w
FROM generate_series(1,10000) AS i;
CREATE INDEX abc ON btg(x,y);
ANALYZE btg;
--为了使得执行计划走排序聚集,需要禁用该参数enable_hashagg
SET enable_hashagg=off;
SET max_parallel_workers= 0;
SET max_parallel_workers_per_gather = 0;

GROUP BY存在的问题

针对PostgreSQL17优化器对GROUP BY优化的场景,我们先来查看PostgreSQL16.3版本的执行计划,在案例中GROUP BY的列和order by列以不同的组合执行,观察是否利可以用索引扫描排序来避免Sort操作。

1、GROUP BY顺序和索引顺序比较

--GROUP BY顺序和索引顺序一致
testdb=# EXPLAIN (COSTS OFF) SELECT count(*) FROM btg GROUP BY x,y;
               QUERY PLAN               
----------------------------------------
 GroupAggregate
   Group Key: x, y
   ->  Index Only Scan using abc on btg
(3 rows)
--GROUP BY顺序和索引顺序不一致
testdb=# EXPLAIN (COSTS OFF) SELECT count(*) FROM btg GROUP BY y,x;
         QUERY PLAN          
-----------------------------
 GroupAggregate
   Group Key: y, x
   ->  Sort
         Sort Key: y, x
         ->  Seq Scan on btg
(5 rows)

2、GROUP BY和ORDER BY的顺序与索引顺序比较

  • 当order by顺序与索引顺序一致时
testdb=# EXPLAIN (COSTS OFF) SELECT count(*) FROM btg GROUP BY y,x order by x,y;
               QUERY PLAN               
----------------------------------------
 GroupAggregate
   Group Key: x, y
   ->  Index Only Scan using abc on btg
(3 rows)
testdb=# EXPLAIN (COSTS OFF) SELECT count(*) FROM btg GROUP BY x,y order by x,y;
               QUERY PLAN               
----------------------------------------
 GroupAggregate
   Group Key: x, y
   ->  Index Only Scan using abc on btg
(3 rows)

通过执行计划我们也可以很明显的看出,当order by的顺序和索引顺序一致的时候,无论 GROUP BY列的顺序是什么样的,都不影响执行计划结果。

  • 当order by顺序与索引顺序不一致时
testdb=# EXPLAIN (COSTS OFF) SELECT count(*) FROM btg GROUP BY x,y order by y,x;
         QUERY PLAN          
-----------------------------
 GroupAggregate
   Group Key: y, x
   ->  Sort
         Sort Key: y, x
         ->  Seq Scan on btg
(5 rows)

testdb=# EXPLAIN (COSTS OFF) SELECT count(*) FROM btg GROUP BY y,x order by y,x;
         QUERY PLAN          
-----------------------------
 GroupAggregate
   Group Key: y, x
   ->  Sort
         Sort Key: y, x
         ->  Seq Scan on btg
(5 rows)

通过执行计划我们可以看出,当order by的顺序和索引顺序不一致的时候,无论 GROUP BY列的顺序是什么样的,在扫描表的时候无法使用到索引,因此使用的是顺序扫描的方式。

下面我们来对上面PostgreSQL16.3版本group by的问题简单的汇总一下

  • 在语句中没有order by子句时,GROUP BY顺序和索引顺序不一致时,未使用到索引
  • 当语句中有order by子句时且顺序与索引顺序不一致时,未使用到索引

其实对于上面的两种情况,问题原因是一样的,就是对于Group Agg,只是按照Group By中指定列的顺序和索引列的顺序进行比较keys,因此无法使用索引。

但是对于Group Agg,我们只是按照查询中指定的顺序比较键

解决方案

对于上述的问题,解决思路就是利用了group by并不意味着必须固定的顺序排序,而且可以以任意的顺序排序,而不影响最终的结果。下面我们来验证一下结果

testdb=# SELECT x,y, count(*) FROM btg where x<10 GROUP BY y,x ;
 x | y | count 
---+---+-------
 0 | 0 |   100
 1 | 1 |   100
 2 | 2 |   100
 3 | 3 |   100
 4 | 4 |   100
 5 | 5 |   100
 6 | 6 |   100
 7 | 7 |   100
 8 | 8 |   100
 9 | 9 |   100
(10 rows)

testdb=# SELECT x,y, count(*) FROM btg where x<10 GROUP BY x,y ;
 x | y | count 
---+---+-------
 0 | 0 |   100
 1 | 1 |   100
 2 | 2 |   100
 3 | 3 |   100
 4 | 4 |   100
 5 | 5 |   100
 6 | 6 |   100
 7 | 7 |   100
 8 | 8 |   100
 9 | 9 |   100
(10 rows)

测试的结果是和预期是一样的,group by顺序并不会影响最终数据的结果。

优化场景

GROUP BY顺序和索引顺序不一致

--PostgreSQL17版本优化后的执行计划
testdb=# EXPLAIN (COSTS OFF) SELECT count(*) FROM btg GROUP BY y,x;
               QUERY PLAN               
----------------------------------------
 GroupAggregate
   Group Key: x, y
   ->  Index Only Scan using abc on btg
(3 rows)

从PostgreSQL17版本执行计划我们也可以看到,即使GROUP BY顺序和索引顺序不一致,也可以使用到创建的索引;另外在执行计划中我们也可以看到Group Key的顺序是以索引的顺序来分组的。

ORDER BY顺序与索引顺序不一致时

testdb=# EXPLAIN (COSTS OFF) SELECT count(*) FROM btg GROUP BY x,y order by y,x;
                  QUERY PLAN                  
----------------------------------------------
 Sort
   Sort Key: y, x
   ->  GroupAggregate
         Group Key: x, y
         ->  Index Only Scan using abc on btg
(5 rows)

testdb=# EXPLAIN (COSTS OFF) SELECT count(*) FROM btg GROUP BY y,x order by y,x;
                  QUERY PLAN                  
----------------------------------------------
 Sort
   Sort Key: y, x
   ->  GroupAggregate
         Group Key: x, y
         ->  Index Only Scan using abc on btg
(5 rows)

从PostgreSQL17版本执行计划我们也可以看到,优化后的执行计划中可知,即使ORDER BY顺序和索引顺序不一致,也可以使用到创建的索引;另外在执行计划中我们也可以看到Group Key的顺序同样是以索引的顺序来分组的,与sql中指定的分组顺序没有关系。

适用于增量排序

--该sql语句在PostgreSQL16.3版本的执行计划和PostgreSQL17是一致的
testdb=# explain (COSTS OFF) SELECT x,y FROM btg GROUP BY x,y,z,w;
               QUERY PLAN                
-----------------------------------------
 Group
   Group Key: x, y, z, w
   ->  Incremental Sort
         Sort Key: x, y, z, w
         Presorted Key: x, y
         ->  Index Scan using abc on btg
(6 rows)
--PostgreSQL17优化后执行计划
testdb=# explain (COSTS OFF) SELECT x,y FROM btg GROUP BY z,y,w,x;
               QUERY PLAN                
-----------------------------------------
 Group
   Group Key: x, y, z, w
   ->  Incremental Sort
         Sort Key: x, y, z, w
         Presorted Key: x, y
         ->  Index Scan using abc on btg
(6 rows)
--PostgreSQL17优化后执行计划
testdb=# explain (COSTS OFF) SELECT x,y FROM btg GROUP BY w,z,x,y;
               QUERY PLAN                
-----------------------------------------
 Group
   Group Key: x, y, w, z
   ->  Incremental Sort
         Sort Key: x, y, w, z
         Presorted Key: x, y
         ->  Index Scan using abc on btg
(6 rows)
--PostgreSQL17优化后执行计划
testdb=# explain (COSTS OFF) SELECT x,y FROM btg GROUP BY w,x,z,y;
               QUERY PLAN                
-----------------------------------------
 Group
   Group Key: x, y, w, z
   ->  Incremental Sort
         Sort Key: x, y, w, z
         Presorted Key: x, y
         ->  Index Scan using abc on btg
(6 rows)

从PostgreSQL17版本执行计划我们也可以看到,当语句中没有order by子句时,不论 GROUP BY中的分组以任何顺序排序,都可以使用到索引;另外在执行计划中我们也可以看到Presorted Key的顺序就是索引的顺序;Sort Key是以Presorted Key的顺序为准,并添加剩余的字段;Group Key的顺序就是增量排序的顺序。

子查询

--PostgreSQL16.3执行计划
testdb=# explain (COSTS OFF) SELECT x,y
testdb-# FROM (SELECT * FROM btg ORDER BY x,y,w,z) AS q1
testdb-# GROUP BY (w,x,z,y);
                        QUERY PLAN                        
----------------------------------------------------------
 Group
   Group Key: q1.w, q1.x, q1.z, q1.y
   ->  Sort
         Sort Key: q1.w, q1.x, q1.z, q1.y
         ->  Subquery Scan on q1
               ->  Incremental Sort
                     Sort Key: btg.x, btg.y, btg.w, btg.z
                     Presorted Key: btg.x, btg.y
                     ->  Index Scan using abc on btg
(9 rows)
--PostgreSQL17优化后执行计划
testdb=# explain (COSTS OFF) SELECT x,y
testdb-# FROM (SELECT * FROM btg ORDER BY x,y,w,z) AS q1
testdb-# GROUP BY (w,x,z,y);
                  QUERY PLAN                  
----------------------------------------------
 Group
   Group Key: btg.x, btg.y, btg.w, btg.z
   ->  Incremental Sort
         Sort Key: btg.x, btg.y, btg.w, btg.z
         Presorted Key: btg.x, btg.y
         ->  Index Scan using abc on btg
(6 rows)
============================================第二条sql===========================================
--PostgreSQL16.3执行计划
testdb=# explain (COSTS OFF) SELECT x,y
testdb-# FROM (SELECT * FROM btg ORDER BY x,y,w,z LIMIT 100) AS q1
testdb-# GROUP BY (w,x,z,y);
                           QUERY PLAN                           
----------------------------------------------------------------
 Group
   Group Key: q1.w, q1.x, q1.z, q1.y
   ->  Sort
         Sort Key: q1.w, q1.x, q1.z, q1.y
         ->  Subquery Scan on q1
               ->  Limit
                     ->  Incremental Sort
                           Sort Key: btg.x, btg.y, btg.w, btg.z
                           Presorted Key: btg.x, btg.y
                           ->  Index Scan using abc on btg
(10 rows)
--PostgreSQL17优化后执行计划
testdb=# explain (COSTS OFF) SELECT x,y
testdb-# FROM (SELECT * FROM btg ORDER BY x,y,w,z LIMIT 100) AS q1
testdb-# GROUP BY (w,x,z,y);
                     QUERY PLAN                     
----------------------------------------------------
 Group
   Group Key: btg.x, btg.y, btg.w, btg.z
   ->  Limit
         ->  Incremental Sort
               Sort Key: btg.x, btg.y, btg.w, btg.z
               Presorted Key: btg.x, btg.y
               ->  Index Scan using abc on btg
(7 rows)

通过以上对子查询执行计划的对比,我们可以看到执行计划的差异还是很明显的,对于子查询外面的GROUP BY 即使指定的顺序与索引不一致,也用到了索引。

总结

总的来说,当使用多列GROUP BY子句计算查询时,如果我们将GROUP BY子句的顺序与order BY排序子句或索引顺序保持一致,则可以最小化或避免排序操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/740099.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

若依-前后端分离项目学习

第一天&#xff08;6.24&#xff09; 具体参考视频 b站 楠哥教你学Java 【【开源项目学习】若依前后端分离版&#xff0c;通俗易懂&#xff0c;快速上手】 https://www.bilibili.com/video/BV1HT4y1d7oA/?share_sourcecopy_web&vd_sourcecd9334b72b49da3614a4257…

“湖北建筑安全员C证考试合格证书不能打印?可能是你犯了这个错误!“

"湖北建筑安全员C证考试合格证书不能打印&#xff1f;可能是你犯了这个错误&#xff01;" 湖北建筑安全员C证考试合格证书不能打印咋回事 目前建筑安全员C证都是全国联网的&#xff0c;在湖北考的建筑安全员C证在外省也可以正常使用or调转。全国工程质量安全监管信息…

【扫雷游戏】C语言详解

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…

从基础到高级:视频直播美颜SDK的开发教学

本篇文章&#xff0c;小编将从基础到高级&#xff0c;详细讲解视频直播美颜SDK的开发过程&#xff0c;帮助开发者更好地掌握这一技术。 一、基础知识 什么是视频直播美颜SDK&#xff1f; 视频直播美颜SDK包含了一系列用于视频处理的功能模块&#xff0c;特别是美颜效果的实现…

封装vuetify3中v-time-picker组件,并解决使用时分秒类型只能在修改秒之后v-model才会同步更新的问题

目前时间组件还属于实验室组件&#xff0c;要使用需要单独引入&#xff0c;具体使用方式查看官网 创建公共时间选择器组件 common-time-pickers.vue 子组件页面 <template><div><v-dialog v-model"props.timeItem.isShow" activator"parent&q…

对于GPT-5的些许期待

目录 1.概述 2.GPT-5技术突破预测 3.智能系统人类协作 3.1. 辅助决策 3.2. 增强创造力 3.3. 处理复杂任务 3.4.人机协同的未来图景 4.迎接AI技术变革策略 4.1.教育方面 4.2.职业发展方面 4.3.政策制定方面 4.4.人才与技能培养 1.概述 GPT-5作为下一代大语言模型&a…

ONLYOFFICE 8.1全新升级,智能办公体验再升级,引领未来工作新潮流!

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀ONLYOFFICE 8.1 &#x1f4d2;1. ONLYOFFICE简介&#x1f4d9;2. ONLYOFFICE特点&#x1f4d5;3. ONLYOFFICE功能⛰️PDF 文件编辑器&#x1…

【Android】实现图片和视频混合轮播(无限循环、视频自动播放)

目录 前言一、实现效果二、具体实现1. 导入依赖2. 布局3. Banner基础配置4. Banner无限循环机制5. 轮播适配器6. 视频播放处理7. 完整源码 总结 前言 我们日常的需求基本上都是图片的轮播&#xff0c;而在一些特殊需求&#xff0c;例如用于展览的的数据大屏&#xff0c;又想展…

三维点云目标识别对抗攻击研究综述

源自&#xff1a;电子与信息学报 作者&#xff1a;刘伟权 郑世均 郭宇 王程 注&#xff1a;若出现无法显示完全的情况&#xff0c;可 V 搜索“人工智能技术与咨询”查看完整文章 摘 要 当前&#xff0c;人工智能系统在诸多领域都取得了巨大的成功&#xff0c;其中深度学…

云原生架构:未来应用程序设计和部署的革新

目录 前言1. 云原生架构的概述1.1 什么是云原生架构1.2 云原生架构的核心理念 2. 云原生架构的核心特征2.1 容器化应用2.2 微服务架构2.3 自动化管理 3. 云原生架构的优势3.1 弹性和可伸缩性3.2 高可用性和容错性3.3 快速交付和持续部署 4. 实施云原生架构的关键技术4.1 容器编…

对比A100和4090:两者的区别以及适用点

自2022年年末英伟达发布4090芯片以来&#xff0c;这款产品凭借着其优异的性能迅速在科技界占据了一席之地。现如今&#xff0c;不论是在游戏体验、内容创作能力方面还是模型精度提升方面&#xff0c;4090都是一个绕不过去的名字。而A100作为早些发布的产品&#xff0c;其优异的…

【高性能计算笔记】

第1章 - 高性能计算介绍 1. 概念&#xff1a; 高性能计算(High performance computing&#xff0c;缩写HPC)&#xff1a; 指通常使用很多处理器&#xff08;作为单个机器的一部分&#xff09;或者某一集群中组织的几台计算机&#xff08;作为单个计算资源操作&#xff09;的…

宝宝早教电子图书 酷得电子方案

宝宝早教发声书是一种专为婴幼儿设计的图书&#xff0c;旨在通过有趣的图画和声音来吸引宝宝的注意力&#xff0c;帮助他们学习语言、认知和发展各种技能。这类书籍通常包括以下特点&#xff1a; 鲜艳的图画&#xff1a;发声书通常配有色彩鲜艳、形象生动的图画&#xff0c;以…

Linux安装minio及mc客户端(包含ARM处理器架构)

&#x1f353; 简介&#xff1a;java系列技术分享(&#x1f449;持续更新中…&#x1f525;) &#x1f353; 初衷:一起学习、一起进步、坚持不懈 &#x1f353; 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正&#x1f64f; &#x1f353; 希望这篇文章对你有所帮助,欢…

【44 Pandas+Pyecharts | 全国海底捞门店数据分析可视化】

文章目录 &#x1f3f3;️‍&#x1f308; 1. 导入模块&#x1f3f3;️‍&#x1f308; 2. Pandas数据处理2.1 读取数据2.2 查看数据信息2.3 查看描述信息 &#x1f3f3;️‍&#x1f308; 3. Pyecharts数据可视化3.1 各省海底捞门店数量分布柱状图3.2 各省海底捞门店数量分布地…

西南地区某大型钢厂蓝鹏测控又一组测径仪设备投入交付使用

近日&#xff0c;蓝鹏测控为西南地区某大型钢铁厂定制生产的又一台测径仪完成交付安装, 并通过了现场调试验收。这些智能测径仪被广泛应用于各种轧钢生产线&#xff0c;用于检测不同规格的圆棒圆管钢材等。这些设备能够精确测量棒材管材的外径、椭圆度、可以实时显示最大直径, …

os7安装gitlab

gitlab安装要求&#xff1a;os7以上版本&#xff0c;4G内存&#xff0c;磁盘50GB 1.克隆 由于我这里不想影响原来的&#xff0c;所以这里克隆一个os系统。如果其他是第一次安装则不用。 2.修改ip地址 cd /etc/sysconfig/network-scriptsvi ifcfg-ens33 按&#xff1a;insert…

跟《经济学人》学英文:2024年6月22日这期 Think Nvidia looks dear?

Think Nvidia looks dear? American shares could get pricier still Investors are willing to follow whichever narrative paints the rosiest picture 觉得Nvidia看起来很贵&#xff1f;美国股票可能会变得更贵 投资者愿意追随任何一个描绘出最乐观的故事 dear&#x…

一键登录功能实现(采用极光SDK)

前端流程 1. 引入极光认证 SDK&#xff1a; 通过 <script> 标签引入&#xff0c;在 public/index.html 中确认 SDK 脚本已正确加载&#xff1a;参考官网Web SDK 概述 - 极光文档 <!-- 引入极光认证 SDK --> <script type"text/javascript" src&quo…

【权威发布】2024年文化、设计与社会科学国际会议(ICCDSS 2024)

2024年文化、设计与社会科学国际会议 2024 International Conference on Culture, Design, and Social Sciences 会议简介 2024年文化、设计与社会科学国际会议旨在为全球范围内的专家学者提供一个交流文化、设计与社会科学研究成果的平台。会议将围绕文化、设计与社会科学的前…