【发布时间】:2019-12-27 23:21:23
【问题描述】:
我注意到我的所有查询,包括以下查询,在大多数情况下似乎都很快,但会随机变慢,我不知道为什么。
我一直在尝试追查原因,所以我添加了 auto_explain,它只记录了以下查询
START TRANSACTION
UPDATE "recipes" SET "servings" = $2, "updatedAt" = CURRENT_TIMESTAMP
WHERE "id" IN ($1) RETURNING "updatedAt"
COMMIT
Update on public.recipes (cost=0.29..8.30 rows=1 width=1599) (actual time=312.687..312.693 rows=1 loops=1)
Buffers: shared hit=122 read=2 dirtied=4
-> Index Scan using recipes_uid_key on public.recipes (cost=0.29..8.30 rows=1 width=1599) (actual time=0.019..0.023 rows=1 loops=1)
Index Cond: (recipes.id = '5f6d6875-2d32-4306-bf41-7ba541f23592'::uuid)
Buffers: shared hit=3
我觉得奇怪的是它从8.30 跳到312.687 的实际时间并且没有解释那个时间去了哪里。有谁知道这意味着什么?也许行已被锁定,正在等待解锁?
表大小:15K 记录
【问题讨论】:
-
看起来
id是一个主键。您需要大量流量才能使行锁定成为 IMO 因素。有人在做 DDL(ALTER TABLE 类型的事情吗?)或者可能是在您没有提交/回滚的情况下关闭提交的会话? -
会不会是一个在
IN子句中具有大量 id 的查询正在运行,而另一个会话正在尝试更新相同或部分相同的记录?我想这可能会使第二个查询暂停,直到第一个查询完成并解释延迟 -
当查询速度很慢时,是否有任何其他更新/插入查询在同一张表上执行。
-
它总是更便宜。有多个字段,您必须检查它们中的任何一个是否实际更改。使用 postgres 可以大获全胜,因为您可以避免创建多个行版本,这些版本需要稍后清除。
-
对于单行更新,共享缓冲区命中的数量非常大。虽然是点击而不是读取,但它们不应该非常耗时。但无论如何你都应该打开 track_io_timing,以防它显示有用的东西。
标签: sql postgresql sql-update