2009-08-17 117 views
2

我已經將一個字段添加到MySQL表中。我需要用另一個表中的值填充新列。這裏是我想運行的查詢:在750k行執行MySQL更新查詢

UPDATE  table1 t1 
SET   t1.user_id = 
         (
         SELECT t2.user_id 
         FROM  table2 t2 
         WHERE t2.usr_id = t1.usr_id 
         ) 

我在239K行本地運行該查詢,大約需要10分鐘。在我對現場環境做這件事之前,我想問問我在做什麼看起來不錯,即10分鐘聽起來合理。或者我應該以另一種方式做,一個PHP循環?一個更好的查詢?

回答

6

使用UPDATE JOIN!這將爲您提供原生inner join以從中更新,而不是爲每個血腥行運行子查詢。它往往是更快

update table1 t1 
inner join table2 t2 on 
    t1.usr_id = t2.usr_id 
set t1.user_id = t2.user_id 

確保您也有每個usr_id列的索引。這會加速相當多的事情。

如果您有一些行不匹配,並且您想要設置t1.user_id = null,則需要執行left join而不是inner join。如果列已爲null,並且您只是想將其更新爲t2中的值,請使用inner join,因爲速度更快。

我應該提到,爲了後代,這是MySQL語法只有。其他RDBMS有不同的做法update join

+1

此查詢需要一個'LEFT JOIN'來產生相同的結果(即缺少行中的NULL) – Quassnoi 2009-08-17 12:58:10

+0

哇!測試了100行的查詢 - 平均650ms。在兩個表100行上創建索引鍵MUL usr_id avg 7ms! – ed209 2009-08-17 15:50:33

+0

@ ed209:這是多麼驚人的變化可以有多少影響,呃? – Eric 2009-08-17 15:56:35

0

有兩個比較重要的信息丟失:

  1. 什麼類型的表是什麼人?
  2. 它們上面有哪些索引?

如果table2具有包含user_idusr_id作爲前兩列table1被索引上user_id的索引,它不應該是那麼糟糕。

0

您沒有t2.usr_id上的索引。

創建此索引並再次運行您的查詢,或由@Eric(當然是LEFT JOIN)提出的多表UPDATE

請注意,MySQL缺少其他JOIN方法比NESTED LOOPS,所以它是重要的索引,而不是UPDATE語法。

但是,多表UPDATE更具可讀性。