【发布时间】:2019-11-15 16:18:47
【问题描述】:
我正在尝试使更新查询在 Postgres 中运行得更快。该查询相对简单,我已将其分解为将其分布在我的数据库服务器上的所有 CPU 上。
UPDATE p797.line a SET p = 5 FROM p797.pt b WHERE a.source = b.node AND a.id >= 0 and a.id < 40000000
当您在表中的所有行中移动时,“0”和“40000000”被替换为不同的值。 “line”表有 13 亿条记录,pt 表有 5 亿条记录。
目前,这个过程大约需要 16 个小时。我还有其他需要执行的更新查询,如果每个更新查询需要 16 小时,则需要数周才能获得结果。
我发现了一些我想尝试的有趣的东西,但我不确定它是否可以在我的情况下实现,因为我正在通过网络运行查询。
Slow simple update query on PostgreSQL database with 3 million rows
在这里,Le Droid 提到了 COPY,我相信我无法使用这种方法,因为我在网络上运行。他们还使用BUFFER,我不明白如何使用。此外,我的两个表都驻留在同一个数据库中,而不是数据库表和 CSV 的组合。如何按摩我的查询以获得@Le Droid 提到的收益?是否有另一种方法可以用来查看时间收益?我确实看到 Le Droid 提到 HOT 只看到边际收益和大量成本。其他方法?
值得注意的是,我正在 Python 中创建查询并使用 psycopg2 将它们发送到 Postgres 数据库。
编辑:
以下是对上述语句的解释,没有 ID 限制:
"Update on line a (cost=10665536.12..342338721.96 rows=1381265438 width=116)"
" -> Hash Join (cost=10665536.12..342338721.96 rows=1381265438 width=116)"
" Hash Cond: (a.source= b.node)"
" -> Seq Scan on line a (cost=0.00..52953645.38 rows=1381265438 width=102)"
" -> Hash (cost=8347277.72..8347277.72 rows=126271072 width=22)"
" -> Seq Scan on pt b (cost=0.00..8347277.72 rows=126271072 width=22)"
【问题讨论】:
-
是 16 小时只用于块还是所有块?请显示在合理时间内完成的最大查询的 EXPLAIN (ANALYZE, BUFFERS),以及一次更新所有行的查询的 EXPLAIN。你的 work_mem 设置为什么?你有多少可用内存?
-
我有 12 个内核,64Gb 的 RAM。 work_mem = "100MB"。我想弄清楚如何运行 EXPLAIN(ANALYZE, BUFFERS) SQL
-
EXPLAIN(ANALYZE, BUFFERS) UPDATE p797.line a SET p = 5 FROM p797.pt b WHERE a.source = b.node AND a.id >= 0 and a.id < 40000000。请注意,这实际上会执行更新。如果不使用 ANALYZE 运行,它不会执行更新,只需计划如何执行即可。
标签: python postgresql