Postgresql 当WHERE子句被省略时,Postgres更新要慢得多
我正在寻找线索,以理解为什么当Postgresql 当WHERE子句被省略时,Postgres更新要慢得多,postgresql,Postgresql,我正在寻找线索,以理解为什么当WHERE子句上的过滤器被省略时,更新查询变得慢得多 查询的原始版本在负载下运行了200万次,平均每个查询6毫秒: 更新项目 集合名称=$1, 更新了_at=now(), txid=txid_电流(), 版本=版本+1 其中filter1=$2,filter2=$3,version=$4 返回*; 当我取出和version=$4时,相同负载测试下的延迟远更差(236ms): 更新项目 集合名称=$1, 更新了_at=now(), txid=txid_电流(), 版
WHERE
子句上的过滤器被省略时,更新
查询变得慢得多
查询的原始版本在负载下运行了200万次,平均每个查询6毫秒:
更新项目
集合名称=$1,
更新了_at=now(),
txid=txid_电流(),
版本=版本+1
其中filter1=$2,filter2=$3,version=$4
返回*;
当我取出和version=$4
时,相同负载测试下的延迟远更差(236ms):
更新项目
集合名称=$1,
更新了_at=now(),
txid=txid_电流(),
版本=版本+1
其中filter1=$2和filter2=$3
返回*;
filter1+filter2
的元组上有一个唯一的索引,因此它应该始终最多匹配一条记录。PG必须读取整个记录才能生成新的MVCC记录(此查询中还有其他未更新的字段),因此,version=version+1
的成本应该大致相同
出于与我们的应用程序API设计的其他部分相关的某些原因,我需要从这个查询中删除version
子句
我应该看什么,以免遭受性能损失
根据@Laurenz Albe的请求,以下是
解释结果:
with version clause:
UPDATE items
SET name = $1,
updated_at = now(),
txid = txid_current(),
version = version + 1
WHERE filter1 = $2 AND filter2 = $3 AND version = $4
RETURNING *;
Update on items (cost=0.54..8.58 rows=1 width=637) (actual time=0.553..0.559 rows=1 loops=1)
Buffers: shared hit=57
-> Index Scan using filter1_and_filter2 on items (cost=0.54..8.58 rows=1 width=637) (actual time=0.064..0.070 rows=1 loops=1)
Index Cond: (((filter2)::text = 'VBHNTZFLRX1575420065'::text) AND ((filter1)::text = 'UpdateNotifLoadTest'::text))
Filter: (version = 191)
Buffers: shared hit=6
Planning time: 0.138 ms
Execution time: 0.609 ms
---------
without version clause:
UPDATE items
SET name = $1,
updated_at = now(),
txid = txid_current(),
version = version + 1
WHERE filter1 = $2 AND filter2 = $3
RETURNING *;
Update on items (cost=0.54..8.57 rows=1 width=637) (actual time=161.899..161.929 rows=1 loops=1)
Buffers: shared hit=377
-> Index Scan using filter1_and_filter2 on items (cost=0.54..8.57 rows=1 width=637) (actual time=0.102..0.131 rows=1 loops=1)
Index Cond: (((filter2)::text = 'RXDJPVBHNT1575419999'::text) AND ((filter1)::text = 'UpdateNotifLoadTest'::text))
Buffers: shared hit=25
Planning time: 0.140 ms
Execution time: 161.977 ms
奇怪。今天重新运行几次,但无法复制
我以前的方法有一个缺陷。仍然可以繁殖。根据@Bergi的请求,我已经用真实数据更新了活载测试的捕获。请为这两个查询提供解释(分析,缓冲)
输出。也许你有一个包含版本的索引?@LaurenzAlbe:我用这些结果编辑了原始问题。在这些问题中,没有附加条款的版本实际上更快?另一方面,您似乎没有传递真实的数据,因为它没有找到要更新的行,这一点很好。我将看看是否可以从负载测试中捕获一个真正的查询并重试。上周原始问题中报告的延迟数(6ms vs 236ms)在今天的负载测试中重复出现。