2

我需要更新表中的数千行。例如,我有 1000 行 ids - 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,对于一些行的子集,我需要同时设置两者。因此,我需要两个查询。

问题是我有大量的身份证。这个查询大约是 1Mb!

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

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

我不能使用where语句,我的程序中有很多行 ID。

4

2 回答 2

4

创建一个TEMPORARY TABLE并使用您的目标 id 和新值填充它。然后使用带有 FROM子句的 UPDATE 加入该目标并在单个命令中完成。

一般来说,每当你有大量像这样的 id/values 时,如果你先将它们移动到数据库中,生活会变得更容易。

于 2012-12-14T09:05:53.507 回答
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 大得多。

于 2012-12-14T10:13:02.963 回答