【问题标题】:How can I optimize this PostgreSQL query that updates every row?如何优化更新每一行的 PostgreSQL 查询?
【发布时间】:2015-07-23 05:14:26
【问题描述】:

我写了一个查询来更新整个表。如何改进此查询以减少时间:

update page_densities set density = round(density - 0.001, 2)

查询成功返回:628391 行受影响,1754179 毫秒(29 分钟) 执行时间。

编辑:通过设置工作记忆..

set work_mem = '500MB';
update page_densities set density = round(density - 0.001, 2)

查询成功返回:628391 行受影响,731711 毫秒(12 分钟)执行 时间。

【问题讨论】:

  • 任何涉及的限制(在density)可以暂时关闭?您是否尝试分几个步骤执行更新?
  • @Trinimon:这会比使用单个更新语句慢很多。
  • @G.B:在 29 分钟内更新 628391 非常慢。我的猜测是你的硬盘太慢了——也许你的数据库位于网络驱动器上?还是U盘?我有一个在 VM 内运行的相对较慢的服务器 - 更新 500 万行大约需要 8 秒。
  • 我们能否得到“\d page_densities”的输出
  • 不确定这是否同样适用于 PostgreSQL,但在 Oracle 中,如果您在 UPDATE 语句之前发出 LOCK TABLE page_densities IN EXCLUSIVE MODE,此查询的运行速度会显着加快。您还可以考虑: a) 禁用表上的所有触发器(如果有的话); b) 删除所有索引并在更新后重建它们

标签: sql performance postgresql query-performance


【解决方案1】:

假设密度不是索引,您可以使用不同的填充因子来提高性能。有关更多信息,请参阅此问题/答案或 PostgreSQL 文档:

http://www.postgresql.org/docs/9.4/static/sql-createtable.html

Slow simple update query on PostgreSQL database with 3 million rows

虽然您无法修改表的填充因子,但您可以创建一个具有不同填充因子的新表并复制数据。这是一些示例代码。

--create a new table with a different fill factor
CREATE TABLE page_densities_new
(
 ...some fields here
)
WITH (
  FILLFACTOR=70
);

--copy all of the records into the new table
insert into page_densities_new select * from page_densities;

--rename the original/old table
ALTER TABLE page_densities RENAME TO page_densities_old;

--rename the new table
ALTER TABLE page_densities_new RENAME TO page_densities;

在此之后,您将拥有一个与原始表具有相同名称和数据的表,但它具有不同的填充因子。我将它设置为 70,但它可以是 10 到 100 之间的任何值。(100 是默认值)

【讨论】:

    猜你喜欢
    • 2021-07-10
    • 1970-01-01
    • 1970-01-01
    • 2014-06-13
    • 2022-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-12
    相关资源
    最近更新 更多