25

在 pgAdmin 中,每当表的统计信息过期时,它都会提示:

建议运行 VACUUM

表 schema.table 上的估计行数与实际行数有很大偏差。您应该在此表上运行 VACUUM ANALYZE。

我已经使用 pgAdmin 3 和 Postgres 8.4.4 对它进行了测试,autovacuum=off。每当我单击已更改的表时,提示会立即显示。

假设我正在用 Java 制作一个基于 Web 的系统,我如何检测一个表是否已过期,以便我可以显示类似于 pgAdmin 中的提示?

由于我的应用程序的性质,这里有一些我必须遵循的规则:

  1. 我想知道 pg_stats 和 pg_statistic 中某个表的统计信息是否是最新的。

  2. 我无法在 postgresql.conf 中设置 autovacuum 标志。(换句话说,autovacuum 标志可以打开或关闭。我无法控制它。我需要判断统计信息是否是最新的,无论 autovacuum 标志是打开还是关闭。)

  3. 我不能每次都运行真空/分析以使其保持最新。

  4. 当用户选择一个表时,当该表有任何更新(例如删除、插入和更新)未反映在 pg_stats 和 pg_statistic 中时,我需要显示该表已过时的提示。

通过分析 pg_catalog.pg_stat_all_tables 中的时间戳似乎是不可行的。当然,如果一个表之前没有被分析过,我可以在 last_analyze 中检查它是否有时间戳,以确定该表是否是最新的。但是,使用这种方法,当已经有时间戳时,我无法检测表是否是最新的。换句话说,无论我向表中添加多少行,它在 pg_stat_all_tables 中的 last_analyze 时间戳总是用于第一次分析(假设 autovacuum 标志关闭)。因此,我只能在第一次显示“运行 VACUUM 推荐”提示。

通过将 last_analyze 时间戳与当前时间戳进行比较也是不可行的。几天内该表可能没有任何更新。一小时内可能会有大量更新。

鉴于这种情况,我如何始终判断表的统计信息是否是最新的?

4

2 回答 2

33

检查系统目录。

test=# SELECT schemaname, relname, last_analyze FROM pg_stat_all_tables WHERE relname = 'city';
 schemaname | relname |         last_analyze          
------------+---------+-------------------------------
 pagila     | city    | 2011-07-26 19:30:59.357898-07
 world      | city    | 2011-07-26 19:30:53.119366-07
(2 rows)

里面各种有用的信息:

test=# \d pg_stat_all_tables           View "pg_catalog.pg_stat_all_tables"
      Column       |           Type           | Modifiers 
-------------------+--------------------------+-----------
 relid             | oid                      | 
 schemaname        | name                     | 
 relname           | name                     | 
 seq_scan          | bigint                   | 
 seq_tup_read      | bigint                   | 
 idx_scan          | bigint                   | 
 idx_tup_fetch     | bigint                   | 
 n_tup_ins         | bigint                   | 
 n_tup_upd         | bigint                   | 
 n_tup_del         | bigint                   | 
 n_tup_hot_upd     | bigint                   | 
 n_live_tup        | bigint                   | 
 n_dead_tup        | bigint                   | 
 last_vacuum       | timestamp with time zone | 
 last_autovacuum   | timestamp with time zone | 
 last_analyze      | timestamp with time zone | 
 last_autoanalyze  | timestamp with time zone | 
 vacuum_count      | bigint                   | 
 autovacuum_count  | bigint                   | 
 analyze_count     | bigint                   | 
 autoanalyze_count | bigint                   |
于 2011-08-01T21:23:10.283 回答
4

您不必担心应用程序中的空缺。相反,您应该autovac在服务器上配置进程(在 中postgresql.conf),并且服务器VACCUM根据ANALYZE自己的内部统计数据进行处理。您可以配置它应该运行的频率,以及它要处理的阈值变量。

于 2011-08-01T20:59:22.483 回答