【问题标题】:Lookups in for single PostgreSQL table suddenly extremely slow after large update大型更新后,单个 PostgreSQL 表的查找突然变得异常缓慢
【发布时间】:2021-07-03 18:11:44
【问题描述】:

我有一个messages 表,里面有几百万条记录。我的 Rails 应用程序在大多数页面上都包含一个查询,以计算未读 messages 的数量以显示给用户。这个查询 - 以及 messages 表的所有查询 - 没有改变,直到昨天都运行良好。

昨天,我创建了一个新的 messages 列并运行 update_all 来更新我几百万 messages 记录中的每一个的新列。很简单,我之前已经做过很多次了,尽管记录的数量较少。

但是,现在对 COUNT 或 SELECT messages 的每个查询都需要 30 多秒才能返回。在迁移和update_all 之前,执行 COUNT 或 SELECT 只需要 100 毫秒左右。

我尝试了很多方法,但查询仍然非常慢。我试过REINDEX messages,也试过VACCUM messages,但都没有显着帮助。

其余的数据库表仍然照常工作,但是messages 表的这个问题使所有内容都在爬行。有没有人知道为什么会发生这种情况,还有什么我可以尝试解决的问题?

【问题讨论】:

  • 如果没有EXPLAIN (ANALYZE, BUFFERS) 输出,很难确定。

标签: sql postgresql count postgresql-9.6 postgresql-performance


【解决方案1】:

我尝试过REINDEX 消息和VACCUM messages,但都没有显着帮助。

您错过了重要的ANALYZE。可能采用VACUUM ANALYZE 的形式。 (不过,通常autovacuum 应该会处理这个问题!)

更新所有行会在物理关系中创建尽可能多的死元组。为了释放空间,这可能是一个难得的机会

VACUUM FULL ANALYZE messages;

在表上获得排他锁!并且由于您每个用户运行计数很多,您不妨使用CLUSTER

CLUSTER messages USING that_index_sorting_by_user_id_and_the_read_flag

对于每个用户的快速计数,无论哪种方式,适当的(多列)索引都是关键。取决于未公开的架构和查询。

话虽如此,您不应该看到性能出现如此急剧的下降。也许你用尽了资源。就像,只是没有足够的 RAM 来缓存更大的索引。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-28
    • 2015-08-03
    • 2012-01-06
    • 1970-01-01
    • 2018-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多