postgresql - Postgres:如何并行更新独立列?
问题描述
我用大约 1.2 亿行和几列 ( a,b,c,d
) 初始化了一个表。初始化后,我想用一些预先计算的指标来对这些列进行合并,例如a+b, (c+d)/a
等。
独立性假设:实际上,指标是非常昂贵的选择和连接,与问题无关。然而,这些指标是完全独立的(即它们可以并行计算,彼此之间没有任何依赖关系)。这就是为什么我想找到一种说服 postgresUPDATE
并行执行 s 的方法。
只读约束:在这个过程之后,数据库不会以任何方式被修改,即从现在开始,只会SELECT
执行查询。我提到这一点是因为,也许可以稍微放松一下 postgres 锁定系统。
额外列的添加目前分两步执行,如下所示:
- 创建列(按顺序):
ALTER TABLE tab ADD "x" ...;
ALTER TABLE tab ADD "y" ...;
...
- 使用单个指标更新列。我正在并行执行这些更新(通过协程或子进程):
[query 1] UPDATE tab SET "x" = ...
[query 2] UPDATE tab SET "y" = ...
...
锁:即使我能够在它们的只读SELECT
版本中并行运行相同的查询,我也无法执行UPDATE
s。从我读过的内容来看,似乎 postgres 正在锁定单个行以进行更新,这对我的情况来说是不幸的。我要么陷入死锁,要么查询在单个核心上执行并且没有加速(基线是按顺序执行查询)。
问题:如何有效地并行执行许多列独立更新?我正在寻找高级答案而不是实际查询。我应该采取什么方法?
我在阅读各种讨论时考虑过的想法:
- 找到一种禁用逐行锁的方法,然后在单独的查询中计算每个新列(并行)。或者,告诉 postgres 这些查询可以并行运行。
- 计算单个查询中的所有列,但是,将所有行拆分为分离集。然后,为各个行组并行更新这些多列。
- 为每一列创建一个新表,计算单个查询中的指标(将结果保存到新表中)。然后,立即从新表中更新最终表。
谢谢!
编辑 1:其中一个查询是 NULL 值的前向填充。另一个基本上是(a-b)/c
,然而,更复杂的可以看起来像这样(必须重命名表和列):
CREATE TEMPORARY TABLE tmp_speak AS ( -- faster than subselect below
SELECT created
FROM FTable
WHERE event = 'speak'
);
WITH FDiff AS (
SELECT r.id AS id,
(
SELECT f.t
FROM tmp_speak AS f
WHERE r.created <= f.t
ORDER by f.t ASC
LIMIT 1
) - r.created as next_speak
FROM RTable as r
ORDER BY r.id
)
UPDATE RTable
SET next_speak = FDiff.next_speak
FROM FDiff
WHERE RTable.id = FTable.id
解决方案
推荐阅读
- android - 为什么要布局
标签不能与 BottomSheetBehavior 一起正常工作? - vpn - 如何在家中打开公司服务器内的 Web 应用程序?
- nginx - NGINX Amazon EC2 允许通过 80 端口继续加载
- html - 如何使用css将椭圆或圆与线连接
- java - 正则表达式查找以任何语言调用的所有方法
- networking - 到本地主机的 GCloud SSH 隧道
- android - 在受信任的 Web 活动中,地址栏没有隐藏
- ruby-on-rails - 工头开始不启动redis
- python - 如何检查某些特定字符不在字符串中
- python - 为什么在对列表进行切片时,列表中的项目数总是大于结束索引?