2017-10-08 72 views
0

比方说,我们有如下表:更新的不同列

id | col_a | col_b | col_c 
1 | abc | null | qwqw 
2 | null | null | null 
3 | null | ijij | cba 

而我们要做以下更新:

  • 第1行:SET为col_a = CBA
  • 行2:SET col_b = uiui,col_c = zxzx
  • 行3:SET col_b = NULL

首先,是否有可能在一个查询中做到这一点?

如果不是,最好的选择是什么?

  • 每行一个查询,如UPDATE表SET ... WHERE id = 1;
  • 取出行,用新值替换旧值,并执行大量INSERT INTO表VALUES ... ON CONFLICT(id)DO UPDATE SET col_a = EXCLUDED.col_a,col_b = EXCLUDED.col_b,col_c = EXCLUDED .col_c;
  • 还有别的吗?

回答

1

最简单的方法为三updates

update t 
    set col_a = cba 
    where id = 1; 

update t 
    set col_b = uiui, col_c = zxzx 
    where id = 2; 

update t 
    set col_b = null 
    where id = 3; 

所以他们在同一时间的效果,您可以在一个事务中包装这些。假设你有一个id索引,这应该有很好的表现。

你可以把这些成使用条件逻辑一条语句:

update t 
    set col_a = (case when id = 1 then cba else col_a end), 
     col_b = (case when id = 2 then uiui 
         when id = 3 then null 
         else col_b 
       end), 
     col_c = (case when id = 2 then zxzx else col_c end) 
    where id in (1, 2, 3); 

我觉得三个独立的语句更清晰,不易出错。

+0

感谢您的单一声明。这就是我一直在寻找的。你认为它有其他3个独立查询有什么性能优势吗?在这里,我只用3个更新问了我的问题,使其变得简单,但在实际情况中,我会有更多的更新,并且非常频繁,所以我正在寻找任何可能的性能改进。 – leyou

+0

@leyou。 。 。如果where条件使用索引,那么在单个事务中单独更新应该会给出合理的性能。 '冲突'方法很聪明,也应该有效。如果您正在更新表中很大一部分行,则截断并重新插入可能是最快的方法。 –

+0

我通过模拟10,000个随机行更新在笔记本电脑上进行了一些快速测试。每行使用一个查询更新大约需要12秒。使用“选择+插入冲突”大约需要6秒。使用单个语句,大约需要5秒。 – leyou