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

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

2.关键统计信息介绍

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

cpp 复制代码
\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函数。

cpp 复制代码
 在表大小为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。

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

4.优化器使用原理

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

相关推荐
瀚高PG实验室几秒前
瀚高数据库创建新数据库卡住问题排查
数据库·postgresql·瀚高数据库
瑶总迷弟19 分钟前
银河麒麟 V10 ARM64 安装 Oracle 19c 静默部署操作手册
数据库·oracle
飞浪纪元[FWC–FE]44 分钟前
Qt 工程创建与 CMake / qmake 构建规范
开发语言·数据库·qt
Ivanqhz1 小时前
MoE + LLM 应用
数据库·人工智能·pytorch·python·深度学习·算法·1024程序员节
Tsuki_tl1 小时前
【总结】Redis五大数据类型应用场景及基本命令
数据库·redis·后端·缓存·缓存中间件·redis命令·redis 五大数据类型
Gauss松鼠会1 小时前
GaussDB 整体架构解析
运维·服务器·网络·数据库·sql·架构·gaussdb
系统集成-鹰翔1 小时前
ERP对接升级提示数据库迁移失败:SQLite逐版本事务到底回滚到哪一步
javascript·数据库·经验分享·后端
西瓜拿铁好喝1 小时前
开源和闭源 AI 办公工具,分别适合谁
java·前端·数据库
代码派1 小时前
业务不停机迁移 MySQL 到 TiDB,NineData 数据增量同步实操演示
数据库·mysql·tidb·ninedata·无停机迁移·增量迁移·全量迁移
Gauss松鼠会1 小时前
GaussDB 中 gsql 与 DBeaver(JDBC)客户端工具查询时间不一致:原因、排查与处理
运维·服务器·数据库·sql·gaussdb·经验总结