【问题标题】:How do I know if the statistics of a Postgres table are up to date?我如何知道 Postgres 表的统计信息是否是最新的?
【发布时间】:2011-10-17 18:01:32
【问题描述】:

在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. 我无法每次都运行 Vacuum/analyze 以使其保持最新状态。

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

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

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

在这种情况下,我如何才能始终判断表的统计信息是否是最新的?

【问题讨论】:

    标签: postgresql statistics analyzer vacuum


    【解决方案1】:

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

    【讨论】:

    • 嗨亚伦,谢谢你的回答。但是由于我的应用程序的性质,我无法在 postgresql.conf 中设置 autovacuum 标志。 autovacuum 标志可以打开或关闭。我无法控制它。
    • 您能与您的 DBA 取得联系吗?即使它是一个托管应用程序,autovac 守护程序也应该运行,因为没有它,Postgres 会变得非常碎片化,尤其是在您执行大量删除操作时。
    【解决方案2】:

    检查系统目录。

    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                   |
    

    【讨论】:

    • 谢谢你的回答,肖恩。我确实尝试了 pg_stat_all_tables。我能够在分析之前第一次告诉过时的表格。但我不知道如何判断同一张表何时有更多更改。请查看我更新的问题。
    • 好的,我已经了解了如何在向表中添加(或从中删除)行时判断表的统计信息是否是最新的。诀窍是将视图“pg_catalog.pg_stat_all_tables”中的 n_tup_ins(或 n_live_tup)与表“pg_catalog.pg_class”中的 reltuples 进行比较。虽然这种方法在行数保持不变的情况下无法检测到更新,但它满足了我的问题。
    • 只需在后端记录所有查询,然后查看连接 pgAdmin 时会发生什么。请注意来自不同海报的上述关于启用 autovacuum 的评论。你应该使用 autovacuum 运行,除非你有一些特殊的需求,并且准确地知道你试图通过使用 autovacuum 来避免什么(你可能没有,你不应该避免使用 autovacuum)。如果这不是您的决定,请向决策者提出此案。
    猜你喜欢
    • 1970-01-01
    • 2011-02-03
    • 1970-01-01
    • 2013-09-21
    • 1970-01-01
    • 2010-09-16
    • 1970-01-01
    • 2016-04-26
    • 1970-01-01
    相关资源
    最近更新 更多