我想弄明白为什么我们的一个 迁移脚本永远在我们正在尝试进行更新 从另一个表连接以获取相关的数据。
每个表(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,它们不会那么糟糕。
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。
答案 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具有聚簇索引。