2009-08-17 82 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更具可读性。