2.1. 表中元组数据的统计信息
这类统计信息主要通过执行 ANALYZE 命令生成,可作用于整个数据库、指定表或指定列。
其中关系级别的统计信息保存在 pg_class 系统表中:
reltuples:记录表中元组的估计数量;
relpages:记录表的页数;
relallvisible:记录可见性映射中标记为“全部可见”的页面数量;
而列级别的统计信息则存储在 pg_statistic 系统表中,每条元组表示某一列的统计信息,例如:
stanullfrac:该列中 NULL 值的比例;
stawidth:列值的平均宽度;
还有其他字段记录值的分布、最常见值等。
这些统计信息的更新依赖于 ANALYZE 操作。可以由用户手动执行,或由 autovacuum 进程定期触发。所以这些数据具有滞后性,仅反映采样当时的表数据状态。它们的作用是:查询优化器会利用这些统计信息来评估执行计划的成本,从而选择最优的执行路径。
2.2. 数据库运行状态的统计信息
这部分统计信息分为两类:收集型与动态型,主要用于反映数据库的实时运行状态。这类统计信息的作用都是展示数据库的运行状态,用于数据库的运维监控。所以 PG 为上述这两类统计信息也定义了一系列的视图,它们以 pg_stat_ 或 pg_statio_ 开头。
2.2.1. 收集型统计信息
在 PG15 以前,PostgreSQL 的各类进程 (后端进程、归档进程、写入进程等) 在执行期间会调用相应的函数 (如 pgstat_report_stat、pgstat_send_archiver、pgstat_send_bgwriter) 将统计数据发送给专门的统计信息收集进程。而统计信息收集进程会将数据写入临时文件,通常位于 pg_stat_tmp/ 目录下 (该目录可通过 stats_temp_directory 参数配置) 。进程之间的通信采用 UDP 协议。PG 服务器关闭时,这些文件会被存放在 pg_stat/ 目录中,等 PG 再次重启时会重新加载这些文件中的信息,并再次将它们存放在 pg_stat_tmp/ 目录中。
从 PostgreSQL 15 开始,统计信息收集进程被移除了。这些统计信息不再会写入磁盘文件,而是直接存储在共享内存中。从而提升了效率,避免了文件系统 I/O 的额外开销。
但无论是磁盘文件 (PG15 之前) 还是共享内存 (PG15 起) ,这类统计信息都是定期更新的。因此它们仍具有一定的滞后性,只能反映某一时点的系统状态。它们的作用是:查询部分以 pg_stat_* 和 pg_statio_* 命名的视图时,实质上就是从文件或共享内容中读取这些信息。