PostgreSQL技术内幕8:PostgreSQL查询执行器

2024-09-03 21:28

本文主要是介绍PostgreSQL技术内幕8:PostgreSQL查询执行器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

0.简介

执行器是查询编译和存储引擎之间的连接模块,其负责将优化器输出的执行计划,进行初始化、执行,访问存储引擎并获得最终结果返回,本章主要介绍PG的执行器模型和其执行流程。

执行器的处理模型

常见的执行器的处理模型包含基于拉操作的Pull模型和基于推操作的Push模型。

1.1 火山模型(Pull模型)

火山模型也叫迭代器模型,最早是《Volcano, an Extensible and Parallel Query Evaluation System》中提出,其产生的背景是当时的 IO 速度是远远小于 CPU 的计算速度的,所以降低虚函数开销带来的优化微乎其微,且内存空间有限,单个处理更附和当时的场景。火山模型是由上游节点主动pull来驱动下层节点,逐层调用来实现数据的处理。其优缺点也比较明确:
优点:
1)实现简单,通用性好:每个Operator都可以独立实现,不受其他Operator的影响,且不受数据规模限制,可以处理任意规模的数据集。
2)灵活性高:可以灵活控制输出的数量,比如Limit算子及时短路。
缺点:
1)虚函数开销:每次调用GetNext获取一个tuple,会产生大量虚函数调用开销。
2)对应Cache不友好:过多的控制语句和函数调用容易导致缓存失效。

在这里插入图片描述

1.2 Push模型

可以看到,Push模型和Pull模型刚好相反,是从底层元组主动向上传递从而驱动整个流程。Push模型在计划的叶子节点开始执行,每层执行完成后物化然后传递给上一层节点。

在这里插入图片描述

优点:
1)减少函数调用:与Pull模型相比,Push模型显著减少了函数调用次数。
2)Cache命中率高:由于内部处理逻辑一致,Cache命中率得到显著提升。
缺点:
1)内存占用较大:由于每个节点都需要物化处理后的数据,可能导致内存占用升高。

1.3 向量化执行引擎

可以看到,把pull模型一次获取一条改为一个循环,处理完再向上驱动即为Push模型。向量化是对其另一种优化,一次处理一批数据,减少函数调用次数和缓存切换频率,提高执行效率。同时,结合了列式存储和SIMD指令,提高执行器性能。

2. PG执行器

执行器是执行计划和存储引擎之间的关联模块,那么接下来就分别从执行器流程、与执行计划的关联、与存储引擎的关联来进行执行器的分析。

2.1 执行器本身流程

在PG中有四个个用于调用执行器的接口,他们是ExecutorStart、ExecutorRun、ExecutorFinish和ExecutorEnd。其职责如下:

1)ExecutorStart:主要负责初始化各个算子的状态,通过调用standard_ExecutorStart对执行器进行必要的初始化

2)ExecutorRun:执行器运行阶段,通过ExecutorRun来执行算子。

3)ExecutorFinish:统计信息收集和清理。

4)ExecutorEnd:逐层结束下游节点的执行,释放资源。

顺序关系即为:ExecutorStart --> ExecutorRun --> ExecutorFinish -->ExecutorEnd

2.2 执行器与执行计划的关联

与传统执行器直接关联执行计划不同,PG引入了Portal层,负责将查询计划转发,同时根据策略生成路径,其结构如下:

typedef struct PortalData
{/* Bookkeeping data */const char *name;      /* portal's name */const char *prepStmtName;  /* source prepared statement (NULL if none) */MemoryContext portalContext;  /* subsidiary memory for portal */ResourceOwner resowner;    /* resources owned by portal */void    (*cleanup) (Portal portal); /* cleanup hook */....    /* other */
}      PortalData;

Portal提供了三个方法:PortalStart、PortalRun和PortalDrop。
1)PortalStart:初始化Portal参数和策略。
2)PortalRun:根据语句类型选择执行器路径,返回结果。
3)PortalDrop:结束执行器,释放资源。

2.3 执行器和存储引擎的关联

以一个简单的Scan为例,顺序扫描的入口函数为SeqNext,其会调用heap_getnext,heap_getnext内部调用heapgettup,其内部使用就是共享内存和页面对应的部分。

这篇关于PostgreSQL技术内幕8:PostgreSQL查询执行器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1134091

相关文章

解密SQL查询语句执行的过程

《解密SQL查询语句执行的过程》文章讲解了SQL语句的执行流程,涵盖解析、优化、执行三个核心阶段,并介绍执行计划查看方法EXPLAIN,同时提出性能优化技巧如合理使用索引、避免SELECT*、JOIN... 目录1. SQL语句的基本结构2. SQL语句的执行过程3. SQL语句的执行计划4. 常见的性能优

Linux系统中查询JDK安装目录的几种常用方法

《Linux系统中查询JDK安装目录的几种常用方法》:本文主要介绍Linux系统中查询JDK安装目录的几种常用方法,方法分别是通过update-alternatives、Java命令、环境变量及目... 目录方法 1:通过update-alternatives查询(推荐)方法 2:检查所有已安装的 JDK方

springboot自定义注解RateLimiter限流注解技术文档详解

《springboot自定义注解RateLimiter限流注解技术文档详解》文章介绍了限流技术的概念、作用及实现方式,通过SpringAOP拦截方法、缓存存储计数器,结合注解、枚举、异常类等核心组件,... 目录什么是限流系统架构核心组件详解1. 限流注解 (@RateLimiter)2. 限流类型枚举 (

Python实现PDF按页分割的技术指南

《Python实现PDF按页分割的技术指南》PDF文件处理是日常工作中的常见需求,特别是当我们需要将大型PDF文档拆分为多个部分时,下面我们就来看看如何使用Python创建一个灵活的PDF分割工具吧... 目录需求分析技术方案工具选择安装依赖完整代码实现使用说明基本用法示例命令输出示例技术亮点实际应用场景扩

postgresql使用UUID函数的方法

《postgresql使用UUID函数的方法》本文给大家介绍postgresql使用UUID函数的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录PostgreSQL有两种生成uuid的方法。可以先通过sql查看是否已安装扩展函数,和可以安装的扩展函数

MyBatis-Plus通用中等、大量数据分批查询和处理方法

《MyBatis-Plus通用中等、大量数据分批查询和处理方法》文章介绍MyBatis-Plus分页查询处理,通过函数式接口与Lambda表达式实现通用逻辑,方法抽象但功能强大,建议扩展分批处理及流式... 目录函数式接口获取分页数据接口数据处理接口通用逻辑工具类使用方法简单查询自定义查询方法总结函数式接口

MySql基本查询之表的增删查改+聚合函数案例详解

《MySql基本查询之表的增删查改+聚合函数案例详解》本文详解SQL的CURD操作INSERT用于数据插入(单行/多行及冲突处理),SELECT实现数据检索(列选择、条件过滤、排序分页),UPDATE... 目录一、Create1.1 单行数据 + 全列插入1.2 多行数据 + 指定列插入1.3 插入否则更

PostgreSQL中rank()窗口函数实用指南与示例

《PostgreSQL中rank()窗口函数实用指南与示例》在数据分析和数据库管理中,经常需要对数据进行排名操作,PostgreSQL提供了强大的窗口函数rank(),可以方便地对结果集中的行进行排名... 目录一、rank()函数简介二、基础示例:部门内员工薪资排名示例数据排名查询三、高级应用示例1. 每

MySQL 多列 IN 查询之语法、性能与实战技巧(最新整理)

《MySQL多列IN查询之语法、性能与实战技巧(最新整理)》本文详解MySQL多列IN查询,对比传统OR写法,强调其简洁高效,适合批量匹配复合键,通过联合索引、分批次优化提升性能,兼容多种数据库... 目录一、基础语法:多列 IN 的两种写法1. 直接值列表2. 子查询二、对比传统 OR 的写法三、性能分析

PostgreSQL的扩展dict_int应用案例解析

《PostgreSQL的扩展dict_int应用案例解析》dict_int扩展为PostgreSQL提供了专业的整数文本处理能力,特别适合需要精确处理数字内容的搜索场景,本文给大家介绍PostgreS... 目录PostgreSQL的扩展dict_int一、扩展概述二、核心功能三、安装与启用四、字典配置方法