当前位置: 首页 > article >正文

PostgreSQL技术内幕23:PG统计信息的收集和应用

0.简介

数据库统计信息是数据库管理系统(DBMS)中用于优化查询性能和提高数据库效率的重要元数据,其中包含很多关键信息,能够为优化器生成合理的查询计划提供数据支撑,本文将对PG统计信息收集方式,关键的统计信息以及其优化器使用原理方面进行介绍。

1.统计信息收集方式

1.1 统计信息收集的形式(独立进程 or 进程内部处理)

PG统计信息收集在PG15之前使用stats collector(统计信息收集器,一个独立的进程)来进行统计信息收集,收集统计信息需要跟踪每个进程的活动,比如扫描表和索引的次数,或者最后一次vacuum以及自动vacuum在表上的运行时间、运行次数。这些信息都是通过UDP的包传递给该收集进程,这种方法存在很多问题:1)过时的统计信息 2)进程未运行 3)其通过写入临时文件的方式来共享,会带来大量I/O操作。
PG15将其独立进程去掉,做了以下优化:1)不在使用临时文件而是使用共享内存来进行通信统计数据(在startup阶段读取,在shutdown阶段持久化),减少I/O操作。2)不在依赖运行的统计进程,减少统计信息丢失,提高可靠性。3)简化其他进程工作,如vacuum。
因为本文基于PG 11来进行的分析,所以还有独立进程概念,其原理一致,只是形式上的差异。

1.2 统计信息收集的使用方式

PG统计信息收集支持两种操作,一种是手动执行,一种是自动执行
1)手动执行:analyze/vacuum analyze
2) 自动执行:自动执行包含两种,一是在事务提交/回滚时发消息给进程更新信息,另外autovacuum launcher会定期读取文件,当某个表改动超过阈值时便会触发一次提交信息更新操作。

在这里插入图片描述

2.关键统计信息介绍

在PG中,统计信息可以分成两部分,一是数据分布的统计信息,描述数据的分布状况,其存储与pg_statistic系统表中,其不容易阅读,可以查看pg_stats视图来了解其内部信息;另外一类是运行状态的统计数据。其中pg_stats可以使用如下命令查看,具体字段含义见下方表格

\d+ pg_stats

在这里插入图片描述

3. 统计信息收集原理

如何收集统计信息,也就是如何去对信息进行抽样统计,PG抽样算法如下:
1)选择采样函数:内部数据采用acquire_sample_rows,外部表使用外部表插件的实现。
2)获取表的每个字段信息并将结果返回。
3)针对每个字段来进行处理。
在这里插入图片描述

需要说明的是在采样过一次在采样过程中并不会处理事务中的记录(如正在插入和删除的记录),但是如果其是在analyze所在的事务中执行的,就会加入统计,这点可能造成统计顺序不准确(如两次analyze并发执行,结果可能不一致且覆盖,或者长事务结束前后统计信息相差较大)。
另外对于采样的大小,PG的使用的公式来自于论文:《Random sampling for histogram construction: how much is enough?》,PG实现可以看std_typanalyze函数。

 在表大小为n,矩形图大小为k,分组内相关最大相关性错误为f,错误可能为gamma的情况下,最小的样本大小如下:
    r = 4 * k * ln(2*n/gamma) / f^2
    取f=0.5,gamma=0.01,n=10^6,我们可以得到
    r = 305.82 * k
    可以看到,元组数对样本大小的影响很小,即使元组数为10^12,采样出错的概率也不高,因此PG统一使用300作为采样的权值,简化问题,在确定样本大小时无需获取表大小。

使用的随机数算法是Knuth’s Algorithm S。

设k为样本大小, K为抽样对象大小, i为当前对象,V生成的0-1之间的随机数 
while i < k
    p = k/(K - i); 
    if V < p
      pick it
      k--;
    i++

4.优化器使用原理

统计信息在优化器的作用通过一个查询来说明,如果发现满足where的条件很少的话就会倾向于走索引扫描,反之走顺序扫描(减少二次回表)。


http://www.kler.cn/a/521085.html

相关文章:

  • 【Elasticsearch】 索引模板 ignore_missing_component_templates
  • 【YOLOv11改进- 主干网络】YOLOv11+MobileNetV3(2019): 更快,更精准;
  • 如何运用python爬虫爬取知网相关内容信息?
  • 【ComfyUI专栏】ComfyUI 部署Kolors
  • JS面相对象小案例:自定义安全数组
  • 82,【6】BUUCTF WEB .[CISCN2019 华东南赛区]Double Secret
  • 【Leetcode 热题 100】300. 最长递增子序列
  • [SWPUCTF 2022 新生赛]js_sign
  • 【java数据结构】哈希表
  • 2025年美赛数学建模F题 为农业再培养腾出空间
  • 葡萄果品分级以及葡萄簇识别-目标检测数据集
  • SOAFEE 技术研讨会:汽车软件定义与自动驾驶技术探讨
  • arduino学习
  • Kotlin单例类
  • LeetCode - Google 校招100题 第9天 Hard 题汇总 (12题)
  • 2025年数学建模美赛 A题分析(4)楼梯使用人数模型
  • Vuex 的核心概念:State, Mutations, Actions, Getters
  • 提供一种刷新X410内部EMMC存储器的方法
  • 【AI论文】Sigma:对查询、键和值进行差分缩放,以实现高效语言模型
  • AndroidStudio 下载链接
  • Blazor-@typeparam
  • C++资料
  • 序列标注:从传统到现代,NLP中的标签预测技术全解析
  • dev c++ ‘unordered_set‘ does not name a type
  • 工业数据分析:解锁工厂数字化的潜力
  • Pyecharts之饼图与多饼图的应用