Postgresql 序列性能

Posted

技术标签:

【中文标题】Postgresql 序列性能【英文标题】:Postgres SQL sentence performance 【发布时间】:2018-06-05 20:16:36 【问题描述】:

我有一个在 16 核/32 Gb WIndows Server 工作站上运行的 Postgres 实例。

我遵循了在以下位置看到的性能改进提示:https://www.postgresql.org/docs/9.3/static/performance-tips.html

当我运行如下更新时:

analyze;
update amazon_v2 
  set states_id = amazon.states_id, 
  geom = amazon.geom
from amazon
where amazon_v2.fid = amazon.fid

其中fid是两个表的主键,都有68M的记录,运行差不多一天。

有没有办法提高这样的SQL语句的性能?例如,我是否应该编写一个存储过程来逐条处理它?

【问题讨论】:

更新前你真的运行analyze吗? 您确定所有行都需要更新吗?您可以添加and (amazon_v2.states_id <> amazon.states_id or amazon_v2.geom <> amazon.geom) 以减少需要更改的行数 您在states_id 字段上有索引吗?如果 amazon_v2 中的许多行正在更新为 states_id 的不同值,您可能希望删除 states_id 上的索引(如果存在),然后在更新后重建它 问题是我将亚马逊表的一些列导出到csv提交到h2o。现在我需要在新版本的亚马逊表 v2 中将结果返回到数据库。 geom 和 states_id 列在 h2o 中不是必需的,但我需要 amazon_v2 中的那些。这次更新花费了很多时间,我想我将导出 geom 和 states_id,处理数据并使用 /copy 将所有列导入回来。我想它会更快。我认为如果我可以“强制”postgres 使用更多资源,那就太好了。 edit您的问题并为有问题的表(包括所有索引)添加create table语句,您正在使用的查询和生成的execution plan使用 explain (verbose)Formatted text 请no screen shots 【参考方案1】:

您没有显示执行计划,但我敢打赌它可能正在对amazon_v2 执行全表扫描,并在amazon 上使用索引搜索

我不知道如何在此处提高性能,因为它已经接近最佳状态。我能想到的唯一想法是使用表分区和并行化执行。

另一个完全不同的策略是只更新“修改”的行。也许您可以跟踪这些以避免每次都更新所有 6800 万行。

【讨论】:

【参考方案2】:

您的查询是在一个非常日志事务中执行的。该事务可能被其他写入者阻止。查询pg_locks。

长事务对 autovacuum 的性能有负面影响。执行时间是否会增加其他时间?如果,请检查table bloat。

当大交易被分解成小交易时,性能通常会提高。不幸的是,该操作不再是原子的,并且没有关于最佳批量大小的黄金法则。

你也应该听从https://***.com/a/50708451/6702373的建议

我们总结一下:

仅更新修改的行(如果只修改了几行)

检查锁

检查表膨胀

检查硬件利用率(与其他问题相关)

将操作拆分成批次。

用删除/截断和插入/复制替换更新(如果更新更改了大多数行,则此方法有效)。

(如果没有其他帮助)分区表

【讨论】:

“较小的事务”更快的建议是不正确的。 6500 万个事务每更新一行将比一个事务更新 6500 万行慢(总计)。 @a_horse_with_no_name:一个非常大的长事务可能会也可能不会比更新一行的 6500 万个事务更快。一切都取决于系统的确切使用模式。长时间运行的事务通常会降低数据库的整体性能。我编辑了我的答案,用“批次”替换了“较小的交易”,并重写了相关部分。

以上是关于Postgresql 序列性能的主要内容,如果未能解决你的问题,请参考以下文章

postgresql中的范围序列

Hibernate使用PostgreSQL序列不影响序列表

postgresql如何对序列进行创建修改以及删除

为啥 PostgreSQL 可序列化事务认为这是冲突?

PostgreSQL 序列

Postgresql 序列与串行