2017-10-08 66 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