Postgres n_tup_ins 与从未分析过的 table 的行数不匹配

Postgres n_tup_ins vs row count mismatch for a table which was never analyzed

我想弄清楚为什么没有对超过 100 万行的 table 执行任何分析作业。 如果我 运行 以下查询:

select count(*) from variant

我得到1,668,422

然而,当我检索相同 table 的统计信息时:

SELECT relname,
n_tup_ins, n_tup_upd, n_tup_del,
n_live_tup, n_dead_tup,
last_vacuum, last_autoanalyze
FROM pg_stat_user_tables WHERE relname = 'variant';

          relname           | n_tup_ins | n_tup_upd | n_tup_del | n_live_tup | n_dead_tup | last_vacuum | last_autoanalyze
----------------------------+-----------+-----------+-----------+------------+------------+-------------+--------------
 variant_analysis_dependent |    140514 |       530 |         0 |     140514 |        104 |             | 
(1 row)

我们可以看到没有进行任何分析。那么我的期望是 n_tup_ins 等于或大于第一个查询的行数(并且 n_live_tup 等于)。另外 n_tup_ins - n_dead_tup 应该等于 n_live_tup

我有以下设置值:

SELECT name, setting, short_desc from pg_settings where category like 'Autovacuum';
                name                 |  setting  |                                        short_desc                                         
-------------------------------------+-----------+-------------------------------------------------------------------------------------------
 autovacuum                          | on        | Starts the autovacuum subprocess.
 autovacuum_analyze_scale_factor     | 0.1       | Number of tuple inserts, updates, or deletes prior to analyze as a fraction of reltuples.
 autovacuum_analyze_threshold        | 50        | Minimum number of tuple inserts, updates, or deletes prior to analyze.

所以即使使用统计中的元组计数,如果我们应用公式 autovacuum_analyze_scale_factor * number of tuples + autovacuum_analyze_threshold,我们应该得到 0.1 * 140514 + 50 = 14101.4,小于 n_tup_ins = 140514,因此应该触发分析作业,对吧?

我在这里错过了什么?

公式中使用的 'number of tuples' 来自 pg_class,而不是 pg_stat_user_tables。因此,如果您的服务器已崩溃,或者在“right/wrong”时间调用了 pg_stat_reset() 或 kin,则此观察结果很容易解释。