2011-09-27 89 views
2

我正在尋找最好的方法來使用單個查詢一次更新多行。 目前我有:在一個查詢中更新多行非常慢的性能

UPDATE `profiles` SET `name` = CASE `id` WHEN 1 THEN 'John' WHEN 2 THEN 'Jane' END, `gender` = CASE `id` WHEN 1 THEN 'Male' WHEN 2 THEN 'Female' END WHERE `id`=1 OR `id`=2 

但是這大約需要4分鐘才能完成(我真正的查詢是在10場中的2000萬行的數據庫),而不是稱取約1秒單獨的更新查詢。

我想解決爲什麼,究竟發生了什麼?我認爲通過在WHERE子句中指定id可以加快速度。

+0

只是一個快速拍攝。我會爲此準備2個不同的查詢。即使您指定了'WHERE'id'= 1或'id'= 2',使用'CASE'方法也可以強制mysql收集所有的ID。如果您爲每個案例準備查詢並直接使用唯一的'id',則您將有最快的方式來執行此操作。通過使用2個語句,您還有更多清晰的查詢,因爲這種「CASE」方法會使查詢變得奇怪......; ) – Marco

回答

0

你有id的索引嗎?如果不是,這是一個好主意,以創建一個(警告,這可能需要很長的時間,爲此在非高峯時段):

CREATE INDEX id_idx ON profiles (id); 

順便說一句,20萬行對10個字段查詢一個表可以花費很長時間,特別是如果沒有索引或緩存很冷。

更新:對於測試,因爲我很好奇,我試圖重現您的情況。爲此,我編寫了一些測試數據。

DDL:https://gist.github.com/b76ab1c1a9d0ea071965
更新查詢:https://gist.github.com/a8841731cb9aa5d8aa26
Perl腳本來填充表與測試數據:https://gist.github.com/958de0d848c01090cb9d

然而,正如我在我下面的評論已經提到的,MySQL會阻止您插入重複數據因爲id是你的PRIMARY KEY,但不是唯一的。如果您可以對錶格模式進行評論和/或發佈您的DDL,這將有很大幫助。

祝你好運! Alex。

+0

是id是主鍵 – Craig

+0

我是否正確地知道id的值是1或2,並且可能會多次出現?這不是創建密鑰的有效方法。你有沒有在桌子上有一些你可以做出主鍵的唯一ID? –

+0

雖然黑客一些測試腳本,我注意到,如果id不唯一,Mysql(正確)阻止我插入數據。你能不能請我們分享一下DDL表格,'DESCRIBE profiles'是什麼? –

0

您可以發佈配置文件表的DDL嗎?這將有助於查看您設置了哪種類型的索引(例如,我們可以假設id列是這裏的主鍵?)。如果您使用的是MySQL,那麼只需運行'SHOW CREATE TABLE profiles'即可生成DDL。

幾個百分點,可能助陣:

1)您的WHERE子句,而不是一個或使用BETWEEN嘗試。例如 UPDATE profiles

SET `name` = 

CASE `id` WHEN 1 THEN 'John' 

WHEN 2 THEN 'Jane' END, 

`gender` = CASE `id` 

WHEN 1 THEN 'Male' WHEN 2 THEN 'Female' END 

WHERE `id` between 1 and 2; 

2)嘗試分割在單獨的查詢的查詢,以避免使用CASE語句例如

update `profiles` 

set `name` = 'John', 

    `gender` = 'Male' 

where `id` = 1; 

update `profiles` 

set `name` = 'Jane', 

    `gender` = 'Female' 

where `id` = 2; 

我不知道,因爲我不知道你用的是什麼方面的查詢,這是可行的!希望有所幫助。

0

能否請您詳細說明您的所有情況,所以我們有更好的主意。如果你有修復案例更新只爲id = 1和2然後拆分您的查詢在2個查詢,如:

update `profiles` set `name` = 'John', `gender` = 'Male' where `id` = 1; 
update `profiles` set `name` = 'Jane', `gender` = 'Female' where `id` = 2; 
+0

我知道我可以單獨運行這些,我之後是一種在一個查詢中運行它們的方法。 – Craig