Chr*_* W. 2 postgresql performance index gin-index postgresql-performance
我在基于 SSD 的四核虚拟专用服务器 (VPS) 和 Debian Linux (8) 上运行 PostgreSQL 9.4.15。相关表有大约 200 万条记录。
记录经常被插入,甚至更频繁地(不断——至少每隔几秒钟)更新一次。据我所知,我已经为这些操作准备了所有适当的索引,以便快速执行,而且绝大多数时间它们确实会立即执行(以毫秒为单位)。
然而,每隔一小时左右,其中一个UPDATE
查询就会花费过多的时间——比如 10 秒或更长时间。当这种情况发生时,它通常就像“一批”被“阻塞”的查询,几乎同时终止。就好像其中一个查询或其他一些后台操作(例如,真空)正在阻止它们。
表 ,items
有很多列,但我认为以下是唯一可能与问题相关的列:
id INTEGER NOT NULL
(首要的关键)search_vector TSVECTOR
last_checkup_at TIMESTAMP WITHOUT TIME ZONE
这些是相关的索引:
items_pkey PRIMARY KEY, btree (id)
items_search_vector_idx gin (search_vector)
items_last_checkup_at_idx btree (last_checkup_at)
最后,当pg_stat_activity
我的日志文件中发出“连接泄漏”警告时,在组装了一个小脚本以转储(所有活动 Postgres 连接/查询的列表)的内容后,我缩小了可能的罪魁祸首查询/列(假设问题不是外部的,比如行为不端的 VPS)。粗略地说,这些查询似乎一次又一次地出现:
UPDATE items SET last_checkup_at = $1 WHERE items.id = 123245
UPDATE items SET search_vector = [..] WHERE items.id = 78901
这些略有解释,但我真的怀疑缺少任何相关内容。偶尔也会出现其他查询(在其他表上),但这些查询通常看起来只是“不走运”而被卷入其中。
现在,即使第一个查询(设置last_checkup_at
)往往出现在大多数时间,设置的查询search_vector
似乎每次都会出现。(此外,一般来说,第一个查询可能有更多的实例被发出,这使得它更有可能只是偶然出现。)
(我想我在这里寻找解决方案,但即使我把它放在包里,我也想为其他人记录这里的事件......几个月来我一直对这个问题感到困惑,然后才有机会深潜。)
问题似乎出在 Postgres 的“ FASTUPDATE
”机制上。
FASTUPDATE
是在GIN
索引上可用的设置,启用后,会导致对索引的更改(由UPDATE
s引起,并且可能由s引起INSERT
)“排队”。然后,一旦这个“队列”变得太大,挂起的条目就会正确地集成到GIN
索引中。
目的FASTUPDATE
是(毫不奇怪)加快索引更新,但不幸的是,它会导致偶尔的 UPDATE
查询异常缓慢。就我而言,我发现最好预先进行命中(主要是为了避免在我的日志中出现“慢查询”的警告)。
FASTUPDATE
显然默认启用并且自 PostgreSQL 8.4 起可用。我能够像这样禁用它:
ALTER INDEX items_search_vector_idx SET (FASTUPDATE=OFF);
Run Code Online (Sandbox Code Playgroud)
在撰写本文时,我已经运行了将近一个星期,几乎没有慢查询。(除了一个我预计需要很长时间的查询,我几乎没有注意到其他问题。)
您还可以在 Postgres 邮件列表的相关主题中找到更多相关信息。有趣的是,Postgres 开发人员之一(Tom Lane)建议处理FASTUPDATE
待处理项目“不应该阻止并发插入”,但我不确定这是否正确;在我的情况下,我会看到几个查询被“备份”,然后一次完成。
归档时间: |
|
查看次数: |
1009 次 |
最近记录: |