PostgreSQL大表的更新时间

Posted

技术标签:

【中文标题】PostgreSQL大表的更新时间【英文标题】:Update time of a big table in PostgreSQL 【发布时间】:2020-12-13 18:47:09 【问题描述】:

我有一个关于在大约 8 到 10GB 大小的大表上更新性能的问题。 我有一个任务,我应该从具有大约 430 万行的提到大小的表中检测不同的值并将它们插入到某个表中。这部分并不是真正的问题,但它是之后的更新。所以我需要根据我导入的表中创建的行的 id 更新一些列。我正在执行的查询示例是:

UPDATE billinglinesstagingaws as s
SET product_id = p.id
FROM product AS p
WHERE p.key=(s.data->'product'->>'sku')::varchar(75)||'-'||(s.data->'lineitem'->>'productcode')::varchar(75) and cloudplatform_id = 1

如上所述,暂存表大小约为 430 万行和 8-10Gb,从查询中可以看出,它有一个 JSONB 字段,产品表有大约 1500 行。 这大约需要 12 分钟,我不确定这是否可以,我真的很想知道,我能做些什么来加快速度。没有外键约束,两列一起存在唯一约束。暂存表上没有索引。 我附上了查询的查询计划,所以任何建议都会有所帮助。提前致谢。

【问题讨论】:

字符串连接上的 JOIN 将不允许使用任何索引。 DBMS 唯一能做的就是实际执行字符串连接(针对目标表)并进行比较。这基本上就是违反 2NF 时发生的情况。 执行计划最好按格式包含,而不是屏幕截图 【参考方案1】:

评论有点太长了。

更新表中的 430 万行需要一些时间。更新需要时间,因为数据库的 ACID 属性要求每次更新都将一些东西提交到磁盘——通常是日志记录。这还不包括读取记录、更新索引和其他开销的时间。

因此,每秒大约 17,000 次更新还不错。

可能有一些方法可以加快您的查询速度。但是,您将这些描述为新行。这让我想知道您是否可以在创建表格时插入正确的值。您能否在 插入 期间查找适当的值,而不是之后在 update 中查找?

【讨论】:

在创建表时我没有添加确切 ID 的选项。我遇到的问题是我连续有 16 个类似的更新,所以这增加了一些时间。我想到的事实是,以这种方式编写的查询应该锁定整个表(如果我没记错的话),这样会杀死我可能实现的任何数量的并行性。如果我将该更新查询拆分为 20 个较小的更新(甚至更高),其范围内的 id 只会更新表的一部分,那么我可能能够并行运行这些更新,这应该会给我一个好的执行时间.这有意义吗? @СтефанЦолић 。 . .将更新拆分为单独的块是有意义的。更新不应该锁定整个表,它应该锁定行。你的想法很好,但数据库也允许并发更新。

以上是关于PostgreSQL大表的更新时间的主要内容,如果未能解决你的问题,请参考以下文章

带有大表的 Geoserver WFS + PostgreSQL 速度极慢

如何优化大表的 Postgresql ARRAY_AGG 查询?

Postgres清理大表

从大表的子集中对随机行进行最快查询 - postgresql

Postgres:具有(延迟)读写访问权限的大表

Oracle批量更新根据一个大表批量更新另一大表的方法比较