openGauss内核分析-统计信息与行数估计
目录
SQL引擎执行查询主要经历了词法语法解析、查询重写、查询规划和计划执行等步骤。其中,在查询规划过程中,为了生成可执行的最优计划,首先要生成路径,而由于路径存在多样性,因此需要对路径进行淘汰选择。目前优化器进行路径的选择主要是基于估算的代价,因此这种优化器也被称为基于代价的优化器(Cost Based Optimization, CBO)。相对于逻辑优化,这种优化方法是物理优化:根据数据的分布(统计信息)情况来对查询执行路径进行评估,从可选的路径中选择一个执行代价最小的路径进行执行,例如是否选择索引SeqScan vs. IndexScan,选择哪个索引,两表关联选择什么样的连接顺序,选择怎样的具体算法等。
在代价估算时,需要使用基表或连接表的行数,而在很多时候,优化器无法获得准确的行数值,因此需要对行数进行估算(Cardinality Estimation),然后再计算代价。
统计信息
统计信息是物理优化的依据,来源于表信息的统计。其中描述基表数据的特征包括唯一值、MCV(Most Common Value)值等,用于行数估算。
Table-Level表级别统计信息,存储在系统表pg_class。
relptuples总元组数:描述表对应的元组数。
relpages总页面数:描述表对应的磁盘页数。
Column-Level列级别统计信息,存储在系统表pg_statistics,也可以使用视图pg_stats查看数据。
Starelid:表的oid。
Staattnum:表属性编号。
stadistinct:用于描述字段里唯一的非 NULL 数据值的数目,一般用于估算集合分组之后的大小,Join结果集大小。
stanullfrac:用于描述当前列中NULL值在总数中的占比。
属性组{stakind1, stanumbers1, stavalues1}构成PG_STATISTIC表的一个卡槽,在PG_STATISTIC表中有5个卡槽。一般情况下,第一个卡槽存储MCV(Most Common Value)信息:描述出现频率大于一定百分比的值的集合,按照出现的频率进行排序,通常用于表征哪些值上出现了倾斜。第二个卡槽存储Histogram直方图信息,描述除了NULL值、MCV值以外的值的分布情况,一般用于估算选择率。
以MCV卡槽为例属性“stakind1”标识卡槽类型为MCV,其中“1”为“STATISTIC_KIND_MCV”的枚举值;属性stanumbers1与属性stavalues1记录MCV的具体内容,其中stavalues1记录key值,stanumbers1记录key对应的频次。
系统表pg_statistics的定义在文件pg_statistic.h中。
#define STATISTIC_KIND_MCV 1 #define STATISTIC_KIND_HISTOGRAM 2 #define STATISTIC_KIND_CORRELATION 3 #define STATISTIC_KIND_MCELEM 4 #define STATISTIC_KIND_DECHIST 5
统计信息通过analyze命令获得。
表tt的oid为40960,有10000行数据占用345个pages页。第1列unique1的分布情况可以从直方图信息获取,直方图有100个区间,并且没有空值和MCV。第16列string4的分布情况可以通过MCV信息获取,这一列有4个distinct值”AAAAxx” ,”HHHHxx” , “OOOOxx” , “VVVVxx” ,4个值的分布频次都有0.25。
行数估计
行数估算是代价估算的基础,来源于基表统计信息的推算,估算基表baserel、Join中间结果集joinrel、Aggregation中结果集大小,为代价估算做准备。
SQL查询常常带有where约束(过滤条件),比如SELECT * FROM tt WHERE string4 = 'AAAAxx'。知道了约束条件的选择率,也就是知道了通过扫描路径要扫描出来的结果所占的比例或者通过连接操作所获得的元组所占的比例,通过这个比例就可以推算出中间结果和最终结果的数量,进而使用这些数量来计算代价。
这里重点分析基表的简单查询——基于OpExpr类型的选择率计算,处理函数在clause_selectivity。如果是过滤条件就调用restriction_selectivity函数来获得OpExpr表达式的选择率,如果是连接条件则调用join_selectivity函数来获得选择率。
SELECT * FROM tt WHERE string4 = 'AAAAxx'为过滤条件,调用restriction_selectivity进行选择率估算。
restriction_selectivity函数识别出string4 = 'AAAAxx'是形如Var = Const的等值约束,操作符的约束选择性计算函数存储在系统表PG_OPERATOR,opno = 93对应的选择率计算函数为eqsel,通过eqsel函数调用var_eq_const函数进行选择率估算。在该过程中,var_eq_const函数会读取PG_STATISTIC表中string4列分布信息,并利用MCV信息直接返回选择率为0.25。
函数set_baserel_size_estimates计算估计行数。
函数调用关系:standard_planner-> subquery_planner-> grouping_planner-> query_planner-> make_one_rel-> set_base_rel_sizes-> set_rel_size-> set_plain_rel_size-> set_baserel_size_estimates-> clauselist_selectivity-> clause_selectivity-> restriction_selectivity-> OidFunctionCall4Coll-> eqsel->var_eq_const

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
因问题太多,Python 3.11 可能会推迟到 12 月发布
Python 3.11 是一个大版本,且带来了约 25% 的性能提升。但近日 Python 核心开发者Pablo在邮件中宣布,由于一些重要的性能 Bug 和崩溃问题,预计在 10 月底发布的 Python 3.11 稳定版本可能要推迟到 12 月。 Python 3.11 Beta 4 已经比计划发布的时间晚了三周,因为下面这些“一堆未处理的、影响发布的问题”。最难受的是,这已经是团队修复了很多"阻止Beta 4 发布"的 Bug 之后才出现的新问题,其中一些 Bug 还是在最后一次更新后发现的,这意味着Python 3.11 Beta 4 的发布时间都要随着修 Bug 而延后。 因此,Python 核心团队在与指导委员会讨论后,正在考虑将3.11 的最终版本推迟到 12 月,以便再发布两个 beta 版本。 如果上图中组织发布的问题在本周末之前未修复,那么 Python 3.11 将多发布两个测试版(每个测试版 1 个月),那么Python 11最终版本将肯定推迟到 12 月。 如果这些阻止发布的程序在本周末之前已修复,那么 Python 3.11.0Beta 4将在下周一发布,这或...
- 下一篇
在解决了 2961 个用户反馈后,我做出了这样的改变...
2961个问题?这么多?没错,Zadig 开源这一年来,也就平均每天十几到几十个问题吧,其实准确的数字不可能知道,但量大是一定的!这一年与社区小伙伴相处过程,也是我职业生涯心得最多/成长最快的一年,想知道我的故事吗?那继续往下看! 大家好我叫 MinMin,本科毕业于 UIUC,(对,就是那个发明了网景 netscape 浏览器的鸡蛋森的母校) 社区小伙伴应该对我比较熟悉,没错,下面这个正是在下。 当然也经常活跃在 GitHub 上,时不时会看到我的回复,这个也是我。 Zadig 的每次发布的英文版 Release Note 翻译,还是我。 工作这么杂,想必不是开发工程师吧,不不不。。下面我给大家讲讲我的研发经历。 职场摸索 那是 2020 年的 11 月,在经历 2 年的职业探索期后,以纯正的 Golang 工程师加入到 KodeRover 团队,当时主要做一些业务模块的开发,彼时对云原生和容器技术产生了浓厚的兴趣。回想过去多少有点好高骛远、眼高手低,但经历一系列打怪经历,像是代码仓导入服务,工作流定时器、触发器的重构等功能的开发,直到 2021 年 7 月 Zadig 正式开源,我...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- CentOS关闭SELinux安全模块
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- CentOS6,CentOS7官方镜像安装Oracle11G
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Hadoop3单机部署,实现最简伪集群
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- SpringBoot2整合Redis,开启缓存,提高访问速度
- Windows10,CentOS7,CentOS8安装Nodejs环境