为什么MySQL UPDATE会永远消失?

时间:2009-10-20 19:05:27

标签: sql mysql database performance

我想弄明白为什么我们的一个 迁移脚本永远在我们正在尝试进行更新 从另一个表连接以获取相关的数据。

每个表(A,B)大约有100,000行。

# now populate the ACHIEVEMENT_INSTANCE.OBJECTIVE_INSTANCE_ID
update A a, B b
set a.INSTANCE_ID = b.INSTANCE_ID
where a.ID = b.ID;

好像我们正在处理创建一些的INNER JOIN 笛卡尔积的类型在2表100,000 100,000之间 正在采取永远(可能很长时间)。

根据MySQL更新默认情况下使用内连接不确定我们是否 可以使用一些其他类型的JOIN,它们不会那么糟糕。

MySQL documentation UPDATE

UPDATE [LOW_PRIORITY] [IGNORE] table_references
   SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...
   [WHERE where_condition]
  

table_references子句列出了   参与联接的表。它的   语法在Section中描述   12.2.8.1,“JOIN语法”。这是一个例子:UPDATE项目,月份SET   items.price = month.price WHERE   items.id = month.id;前面的   示例显示了使用的内部联接   逗号运算符,但是多表   UPDATE语句可以使用任何类型的   SELECT语句中允许join,   例如LEFT JOIN。

3 个答案:

答案 0 :(得分:2)

尝试显式联接以查看它是否可以提高性能:

update A a
join B b on a.ID = b.ID
set a.INSTANCE_ID = b.INSTANCE_ID

答案 1 :(得分:2)

评论中所述的Greg

  

你有关于a.ID和b.ID的索引吗?

我们没有这些列的索引。一旦我们添加它们,查询花了30秒:

create index id_idx on A(id);
create index id_idx on B(id);

答案 2 :(得分:0)

MySQL现在不支持相关子查询吗?

如果是这样,试试这个:

 update A a, B b
 set a.INSTANCE_ID = (SELECT b.INSTANCE_ID FROM B b WHERE a.ID = b.ID);

(上面假设每个A都有一个B - 如果不是,你需要一个WHERE EXISTS()来避免用空值覆盖其他a.INSTANCE_ID。

可能是查询优化器没有选择正确的连接类型,或者存在锁定问题。

它也可能是索引问题 - 例如,如果a.INSTANCE_ID具有聚簇索引。