如何更新PostgreSQL中的大量行?

时间:2012-12-14 08:55:24

标签: postgresql query-optimization

我需要更新表中的数千行。例如,我有1000行带有ID - 1,2 ... 1000:

mytable:
| id   | value1 | value2 |
|  1   |  Null  |  Null  |
|  2   |  Null  |  Null  |
...
| 1000 |  Null  |  Null  |

现在我需要改变前10行。我可以这样做:

UPDATE mytable SET value1=42, value2=111 WHERE id=1
...
UPDATE mytable SET value1=42, value2=111 WHERE id=10

这需要很多请求而且速度不是很快,所以我决定进行这种优化:

UPDATE mytable SET value1=42  WHERE id in (1, 2, 3.. 10)
UPDATE mytable SET value2=111 WHERE id in (1, 2, 3.. 10)

注意:在这种情况下,我实际上可以编写SET value1=42, value2=111,但在实际应用程序中,这组ID不同,对于我需要设置value1的一行,对于其他行 - value2,对于我需要设置的某些行子集。因此,我需要两个查询。

问题是我有很多id。这个查询是关于1Mb的!

Q1 :这是优化此更新的正确方法吗?

Q2 :发送如此大的查询是否正确?我可以通过将此查询划分为几个较小的部分来获得更快的更新吗?

我无法使用where语句,我的程序中只有很多行ID。

2 个答案:

答案 0 :(得分:4)

创建一个TEMPORARY TABLE并使用您的目标ID和新值填充它。然后使用UPDATE with FROM子句连接到该目标并在单个命令中执行。

一般情况下,只要你有大量的id /值,如果你先把它们移到数据库中就会变得容易。

答案 1 :(得分:1)

Q1 :这是优化此更新的正确方法吗?

仍然可以使用CASE ... WHEN句法结构在一个查询中编写它:

UPDATE mytable SET
  value1 = 
    CASE 
      WHEN id IN ( 1, 2, 3, 10) THEN 42
      WHEN id IN (11,12,13, 20) THEN 43
      ELSE value1
    END,
  value2 =    
    CASE 
      WHEN id IN ( 1, 2, 3, 10) THEN 42
      WHEN id IN (11,12,13, 20) THEN 43
      ELSE value2
    END;

等。

您提到您可能需要更新多个位置的行,而上述内容可让您在一个查询中毫无问题地执行此操作。

更新:我忽略了速度是您主要担心的事实(您说“优化”),我的回答在这方面不正确。使用所选答案中解释的临时表可以获得更好的表现。

Q2 :发送如此大的查询是否正确?我可以通过将此查询划分为几个较小的部分来获得更快的更新吗?

我认为Postgresql在处理大型查询时应该有很多问题(甚至远大于1mb)。请记住,SQL DB初始化脚本可能比1mb大。

相关问题