PostgreSQL技术内幕26:PG聚合算子实现分析
文章目录
- 0.简介
- 1.概念说明
- 2.朴素聚集
- 3.Group by聚集
- 3.1 哈希聚集
- 3.2 分组聚集
0.简介
聚合算子在聚合函数在数据分析、报告生成和统计计算中扮演着重要角色,通过对多行数据进行计算,将多个输入值压缩为单一输出值,如求和、平均值、计数等。本文将通过对PostgreSQL聚合算子的源码进行解析,深入了解其实现机制。
1.概念说明
聚合函数:聚合函数是用于对一组值进行计算并返回单个结果的函数。它们通常与GROUP BY子句结合使用,将数据分组后对每组进行计算。例如,COUNT函数用于计算行数或非NULL值的数量,SUM函数用于计算数值列的总和,AVG函数用于计算数值列的平均值,MAX和MIN函数分别用于计算数值列中的最大值和最小值。
常见实现:常见的聚合算子实现分为两种,一种是基于哈希表的实现(哈希聚集),另外一种是基于排序的实现(分组聚集),这两种聚集方式一般来说都是对于带有group by的查询来说的。因为对于没有group by的查询来说,只需要扫描一遍表并对相应元组进行累计操作即可(也被称为朴素聚集)。
聚合整体实现:PG聚合操作整体可以分为三个步骤:1.扫描数据并生成中间值;2.收集并对中间值进行合并(并行场景下需要);3.最终结果生成。这几个步骤可以在pg_aggregate系统表对应查看,下面是sum函数int类型对应的信息,主要看以下几个信息,aggtranstype表示中间值是一个数组,初始值agginitval是空,也就是0,三个基本步骤就是aggtransfn、aggcollectfn、aggfinalfn列。
postgres=# select * from pg_aggregate where aggfnoid = 2109;aggfnoid | aggkind | aggnumdirectargs | aggtransfn | aggfinalfn | aggcombinefn | aggserialfn | aggdeserialfn | a
ggmtransfn | aggminvtransfn | aggmfinalfn | aggfinalextra | aggmfinalextra | aggfinalmodify | aggmfinalmodify | a
ggsortop | aggtranstype | aggtransspace | aggmtranstype | aggmtransspace | agginitval | aggminitval
----------------+---------+------------------+------------+------------+--------------+-------------+---------------+---
-------------+--------------------+--------------+---------------+----------------+----------------+-----------------+--
---------+--------------+---------------+---------------+----------------+------------+-------------pg_catalog.sum | n | 0 | int2_sum | - | int8pl | - | - | in
t2_avg_accum | int2_avg_accum_inv | int2int4_sum | f | f | r | r |0 | 20 | 0 | 1016 | 0 | | {0,0}
(1 row)
2.朴素聚集
因为sum函数并不需要最后的最终结果生成,只需要转换函数即可,所以下面会以求平均值作为例子,扫描数据并生成中间值就是将所有元组进行累加,最终结果生成就是对累加结果进行sum/count。

上图展示了无并行的朴素聚集的流程,但由于是单进程实现而聚集又是一个cpu密集算子,其不能利用cpu多核的优势,从而导致性能的瓶颈。而解决方案就是并行进行扫描和初始聚集,由leader节点进行收集和后处理。

3.Group by聚集
3.1 哈希聚集
非并行哈希函数整体包含两个阶段:1.执行数据扫描构建哈希表;2.执行后处理然后输出给上层算子。
第一个步骤做的实际就是扫描元组然后计算其对应的哈希值,如果不存在需要插入,如何存在则更新。
static void
agg_fill_hash_table(AggState *aggstate)
{TupleTableSlot *outerslot;ExprContext *tmpcontext = aggstate->tmpcontext;/** Process each outer-plan tuple, and then fetch the next one, until we* exhaust the outer plan.*/for (;;){outerslot = fetch_input_tuple(aggstate);if (TupIsNull(outerslot))break;/* set up for lookup_hash_entries and advance_aggregates */tmpcontext->ecxt_outertuple = outerslot;/* Find or build hashtable entries */lookup_hash_entries(aggstate);/* Advance the aggregates (or combine functions) */advance_aggregates(aggstate);/** Reset per-input-tuple context after each tuple, but note that the* hash lookups do this too*/ResetExprContext(aggstate->tmpcontext);}aggstate->table_filled = true;/* Initialize to walk the first hash table */select_current_set(aggstate, 0, true);ResetTupleHashIterator(aggstate->perhash[0].hashtable,&aggstate->perhash[0].hashiter);
}
第二步就是将哈希表进行遍历,依次处理结果并输出给上层算子。
static TupleTableSlot *
ExecAgg(PlanState *pstate)
{AggState *node = castNode(AggState, pstate);TupleTableSlot *result = NULL;CHECK_FOR_INTERRUPTS();if (!node->agg_done){/* Dispatch based on strategy */switch (node->phase->aggstrategy){case AGG_HASHED:if (!node->table_filled)agg_fill_hash_table(node);/* FALLTHROUGH */case AGG_MIXED:result = agg_retrieve_hash_table(node);break;case AGG_PLAIN:case AGG_SORTED:result = agg_retrieve_direct(node);break;}if (!TupIsNull(result))return result;}return NULL;
}
3.2 分组聚集
分组聚集使用的是排序的方式,其和朴素聚集的区别主要是增加了排序流程。代码也可以看,其排序和朴素聚集走了一样的代码:
static TupleTableSlot *
ExecAgg(PlanState *pstate)
{AggState *node = castNode(AggState, pstate);TupleTableSlot *result = NULL;CHECK_FOR_INTERRUPTS();if (!node->agg_done){/* Dispatch based on strategy */switch (node->phase->aggstrategy){case AGG_HASHED:if (!node->table_filled)agg_fill_hash_table(node);/* FALLTHROUGH */case AGG_MIXED:result = agg_retrieve_hash_table(node);break;case AGG_PLAIN:case AGG_SORTED:result = agg_retrieve_direct(node);break;}if (!TupIsNull(result))return result;}return NULL;
}
相关文章:
PostgreSQL技术内幕26:PG聚合算子实现分析
文章目录 0.简介1.概念说明2.朴素聚集3.Group by聚集3.1 哈希聚集3.2 分组聚集 0.简介 聚合算子在聚合函数在数据分析、报告生成和统计计算中扮演着重要角色,通过对多行数据进行计算,将多个输入值压缩为单一输出值,如求和、平均值、计数等。…...
【RS】OneRec快手-生成式推荐模型
note 本文提出了一种名为 OneRec 的统一生成式推荐框架,旨在替代传统的多阶段排序策略,通过一个端到端的生成模型直接生成推荐结果。OneRec 的主要贡献包括: 编码器-解码器结构:采用稀疏混合专家(MoE)架构…...
AVL树的平衡算法的简化问题
AVL树是一种紧凑的二叉查找树。它的每个结点,都有左右子树高度相等,或者只相差1这样的特性。文章https://blog.csdn.net/aaasssdddd96/article/details/106291144给出了一个例子。 为了便于讨论,这里对AVL树的结点平衡情况定义2个名称&#…...
mac安装navicat及使用
0.删除旧的 sudo rm -Rf /Applications/Navicat\ Premium.app sudo rm -Rf /private/var/db/BootCaches/CB6F12B3-2C14-461E-B5A7-A8621B7FF130/app.com.prect.NavicatPremium.playlist sudo rm -Rf ~/Library/Caches/com.apple.helpd/SDMHelpData/Other/English/HelpSDMIndexF…...
【HTML】二、列表、表格
文章目录 1、列表1.1 无序列表1.2 有序列表1.3 定义列表 2、表格2.1 定义2.2 表格结构标签2.3 合并单元格 1、列表 列表分为: 无序列表有序列表定义列表:一个标题下有多个小分类 1.1 无序列表 ul嵌套li,ul是无序列表,li是列表…...
大语言模型安全风险分析及相关解决方案
大语言模型的安全风险可以从多个维度进行分类。 从输入输出的角度来看,存在提示注入、不安全输出处理、恶意内容生成和幻觉错误等风险; 从数据层面来看,训练数据中毒、敏感信息泄露和模型反演攻击是主要威胁; 模型自身则面临拒绝服务和盗窃的风险; 供应链和插件的不安全引…...
windows平台的ffmpeg编译使用
windows平台的ffmpeg编译使用 一、现状 本人使用libgdx开发galGame,发现扩展包gdx-video不支持mp4,不能忍,正好看到官网有支持自定义编译的文档,所以操作一下,自定义编译。本文重点在于操作windows平台,linux平台太简单了。 整个过程包括如下几个步骤。 二、代码下载…...
FFMPEG录制远程监控摄像头MP4
手绘效果图 上图是录制功能的HTML前端页面,录制功能和解码视频放在一起。录制功能关键是录制(开始录制按钮)、停止录像按钮。当点击“录制”的时候则会开始录制MP4文件, 当点击停止的时候就会停止录制MP4。经过录制后,则会生成MP4,并放到我的RV1126的/tm…...
centos操作系统上传和下载百度网盘内容
探序基因 整理 进入百度网盘官网百度网盘 客户端下载 下载linux的rpm格式的安装包 在linux命令行中输入:rpm -ivh baidunetdisk_4.17.7_x86_64.rpm 出现报错: 错误:依赖检测失败: libXScrnSaver 被 baidunetdisk-4.17.7-1.x8…...
Rubick:基于 Electron 的开源插件化桌面效率工具箱
Rubick 是一款基于 Electron 构建的开源桌面工具箱,专为追求高效办公和个性化体验的用户设计。它通过自由集成丰富的插件,让用户能够根据自己的需求打造极致的桌面端效率工具。 软件命名由来Rubick 的名字来源于《DOTA2》中的英雄 Rubick(拉…...
ruoyi-vue部署
ruoyi源码类型 Ruoyi源码 编译打包后,直接部署tomcat服务器 Ruoyi-vue 前后端分离版 前端部署到nginx 后端部署到tomcat RuoYi-Cloud 微服务版 RuoYi-app 移动端版 RuoYi-vue 前后端分离版 环境 JDK>=1.8 MySQL >= 5.7 Maven >= 3.0 Node >= 12 Redis…...
MyBatis 如何创建 SqlSession 对象的?
MyBatis 创建 SqlSession 对象的过程主要由 SqlSessionFactory 接口及其实现类来完成。以下是详细步骤: 1. SqlSessionFactory 接口: SqlSessionFactory 是 MyBatis 的核心接口之一,它负责创建 SqlSession 对象。 你可以将 SqlSessionFactory 视为 Sql…...
LLM论文笔记 23: Meta Reasoning for Large Language Models
Arxiv日期:2024.6.17机构:THU / MSRA 关键词 meta-reasoning推理方法prompt engineering 核心结论 1. 提出Meta Reasoning prompting,MRP是一种系统提示方法,能够帮助LLM动态选择最合适的推理方法,从而提升其灵活性和…...
【最后203篇系列】015 几种消息队列的思考
背景 队列还是非常重要的中间件,可以帮助我们:提高处理效率、完成更复杂的处理流程 最初,我觉得只要掌握一种消息队列就够了,现在想想挺好笑的。 过去的探索 因为我用python,而rabbitmq比较贴合快速和复杂的数据处…...
golang time包和日期函数
1.简介 在程序中日期和时间是我们经常会用到的,在go中time包提供了时间的显示和测量函数。 2.获取当前时间 通过time.Now()函数获取当前时间对象,然后获取时间对象的年月日时分秒等值。 now : time.Now()fmt.Printf("now%v type%T\n", now…...
学习springboot 的自动配置原理
前言 为什么要学习springboot 的自动配置原理? 1学习 自定义成starter 的前提 实际开发中,我们如果定义公共的组件给团队使用,为了让他们使用方便就自定义成starter。而想要学习starter ,就要先了解springboot 的自动配置原理 2 面试需要 了…...
排错 -- FISCO BCOS区块链网络 -- 3. 编译智能合约
文章为FISCO BCOS2.0搭建区块链平台中发现的问题与总结,出错原因不唯一 ,解决办法不唯一 目前社区缺少完整,稳定的搭建平台和教程 ,欢迎各位及时补充,如有错误请及时评论纠正! 感谢各位搜索到这里&#…...
ffmpeg 添加毫秒时间戳
网上有好多添加时间水印的,默认是到秒,而我需要到毫秒,查了一下,没有找到更好的方案,下面是自己实现的方案,可以显示到毫秒。如果有更好的方案,欢迎讨论 ffmpeg -i video.mp4 -vf "drawte…...
centos7上安装Docker
文章目录 **1. 使用华为云镜像源替换Docker仓库****2. 安装Docker CE****3.更换docker镜像源-使用华为云的docker镜像源****4.补充:docker的使用****5.补充:删除docker的步骤** 1. 使用华为云镜像源替换Docker仓库 步骤: 删除无效的Docker仓…...
大模型推理后JSON数据后处理
大模型推理后JSON数据后处理 flyfish LLM 通常指的是 Large Language Model,也就是大语言模型,针对 JSON格式的输出,可以在大模型推理前、推理中、推理后进行处理,这里是在推理后进行处理。 针对模型输出结果,可采用结…...
【干货】Docker 在自动化测试和性能测试中的应用
引言 在现代软件测试领域,Docker 已经成为提升自动化测试和性能测试效率的重要工具。它不仅能提供一致的测试环境,还能大幅减少配置和维护成本。本文将深入探讨 Docker 在自动化测试和性能测试中的应用场景、优势及实践方案。 1. 为什么选择 Docker&am…...
【Linux内核系列】:文件系统收尾以及软硬链接详解
🔥 本文专栏:Linux 🌸作者主页:努力努力再努力wz 💪 今日博客励志语录: 世界上只有一种个人英雄主义,那么就是面对生活的种种失败却依然热爱着生活 内容回顾 那么在之前的学习中,我们…...
视频理解之Actionclip(论文宏观解读)
配合解读代码解读 1.研究背景 1. 视频行为识别的重要性 视频行为识别是视频理解领域的核心任务之一,旨在通过分析视频内容来识别和分类其中的人物行为或活动。这一任务在多个领域具有重要的应用价值,例如智能监控、人机交互、自动驾驶、医疗健康等。随…...
java手机号、邮箱、日期正则表达式
Java正则核心API Java中用 java.util.regex 包的两个类: Pattern:编译正则表达式Matcher:执行匹配操作 1. 验证手机号 String regex "1[3-9]\\d{9}"; boolean isValid "18812345678".matches(regex); // true2. 提取…...
navicat16 升级到 navicat17 之后原来的连接找不到了 mac用户
版本16的路径 注意把对应的路径改成自己的用户名 /Users/自己的用户名/Library/Application Support/PremiumSoft CyberTech/Navicat CC/Common/Settings 版本17的路径 /Users/自己的用户名/Library/Containers/com.navicat.NavicatPremium/Data/Library/Application Suppor…...
Altium Designer——CHIP类元器件PCB封装绘制
文章目录 PCB封装组成元素:焊盘的属性 SS34肖特基二极管SMA(DO-214AC)封装绘制资料:步骤:1.绘制焊盘:用到的快捷键:资料: 2.绘制丝印:用到的快捷键:资料: PCB封装组成元素…...
[C++Qt] 槽函数收不到信号问题(信号的注册)
📢博客主页:https://loewen.blog.csdn.net📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!📢本文由 丶布布原创,首发于 CSDN,转载注明出处🙉📢现…...
【一起来学kubernetes】12、k8s中的Endpoint详解
一、Endpoint的定义与作用二、Endpoint的创建与管理三、Endpoint的查看与组成四、EndpointSlice五、Endpoint的使用场景六、Endpoint与Service的关系1、定义与功能2、创建与管理3、关系与交互4、使用场景与特点 七、Endpoint的kubectl命令1. 查看Endpoint2. 创建Endpoint3. 编辑…...
SpringBoot的并行SQL任务并完成所有任务之后返回操作
一、核心实现方案 1. 线程池配置与异步支持 通过 EnableAsync 启用异步支持,并自定义线程池避免默认线程池的性能问题: Configuration EnableAsync public class AsyncConfig {Beanpublic Executor taskExecutor() {ThreadPoolTaskExecutor executor …...
《AI浪潮中的璀璨新星:Meta Llama、Ollama与DeepSeek的深度剖析》:此文为AI自动生成
《AI浪潮中的璀璨新星:Meta Llama、Ollama与DeepSeek的深度剖析》:此文为AI自动生成 引言:AI 大模型的群雄逐鹿时代 在科技飞速发展的当下,AI 大模型领域已成为全球瞩目的焦点,竞争激烈程度堪称白热化。从 OpenAI 推出…...
