PostgreSQL 18 预览: vacuumdb 添加 “--missing-stats-only” 选项

John Doe 四月 15, 2025

你有没有注意到 PostgreSQL 进行某些变更操作后,会出现统计信息失效的情况?现在,PostgreSQL 提供了可以对缺失统计信息的关系进行分析的方法。

非洲大草原上的一头大象

特性提交日志

vacuumdb:添加仅对缺失统计信息的关系进行分析的选项。

本次提交添加了一个新的--missing-stats-only选项,该选项可与--analyze-only--analyze-in-stages配合使用。当指定此选项时,如果某个关系在列、表达式索引或扩展的统计信息对象方面缺少任何统计信息,vacuumdb将对该关系进行分析。

这个新选项主要用于在使用pg_upgrade升级数据库之后(因为现在升级后,大部分优化器的统计信息能够保留下来),不过在其他情况下可能也会有用。

讨论:https://postgr.es/m/Z5O1bpcwDrMgyrYy%40nathan

示例

在使用 pg_upgrade 对 PostgreSQL 进行大版本升级后,会丢失所有对象的统计信息,这是 PostgreSQL 中一个令人头疼的问题。收集 / 生成这些统计信息所花费的时间,可能比实际升级过程还要长得多,这十分令人困扰。针对这一问题,PostgreSQL 18 为 vacuumdb 新增了一个开关选项。

在查看这个新功能之前,我们需要一个没有任何统计信息的对象,和一个已经有统计信息的对象:

create table t ( a int, b text );

create table tt ( a int, b text );

insert into t select i, 'aaa' from generate_series(1,10) i;

insert into tt select i, 'aaa' from generate_series(1,1000000) i;

第一次插入操作不会触发统计信息收集,而第二次插入操作会触发:

select relname, last_autoanalyze from pg_stat_all_tables where relname in ('t','tt');
 relname |       last_autoanalyze
---------+-------------------------------
 tt      | 2025-03-20 10:18:03.745504+01
 t       |
(2 rows)

vacuumdb 的新选项的作用是,仅对没有任何统计信息的对象收集统计信息:

postgres@pgdev$ vacuumdb --help | grep missing
      --missing-stats-only        only analyze relations with missing statistics

使用这个选项后,我们应该会看到第一个表有了新的统计信息,而第二个表则没有:

postgres@pgdev$ vacuumdb --analyze-only --missing-stats-only postgres
vacuumdb: vacuuming database "postgres"
postgres@pgdev$ psql -c "select relname, last_analyze from pg_stat_all_tables where relname in ('t','tt');"
 relname |         last_analyze
---------+------------------------------
 tt      |
 t       | 2025-03-20 10:24:36.88391+01
(2 rows)

非常不错的体验。感谢社区的所有相关人员。

参考

提交日志:https://git.postgresql.org/pg/commitdiff/edba754f052ea0c02287080004aa6051eaa4f597