DB引擎:InnoDB
两表A,B表均为6W+的记录。用B表的信息更新A表。
SQL:update A left join B on A.field1 = B.field1 and A.field2 = B.field2
set A.field3 = B.
field3, A.field4 = B.field4
无引擎时:每1000更新需要2分11秒,全部更新大概需要2~3小时。
此时加入索引:CREATE INDEX field1_Index ON `A`(`field1`);
注:1、此处只加field1是因为 field2的内容变化很小,就那几个值。
2、此SQL里的字段都不是主键
再次执行SQL,效率依旧。似乎索引没有作用。为了验证我的想法,查看了执行方式:
explain update A left join B on A.field1 = B.field1 and A.field2 = B.field2 set A.field3 = B.field3, A.field4 = B.field4
果然在执行时,没用到索引。找到症结,那就继续找为什么索引没有被用的原因。
查找过程省略,直接上结果。
因为是update,所以我认为 左联和直联,对于结果没有区别,但是从左联改为直联后,
再查询执行方式,发现就能使用索引(原因暂不知道,以后知道了再写)
于是再次执行如下SQL:
update A inner join B on A.field1 = B.field1 and A.field2 = B.field2 set A.field3 = B.field3, A.field4 = B.field4
6W+的数据执行时间:1.43秒
优化完毕。
另,因为以上字段都非主键,所以 SQL修改成以下方式执行似乎更快,查询执行方式,用到了主键索引和我自己加的索引
update A left join B on A.field1 = B.field1 and A.field2 = B.field2
set A.field3 = B.field3, A.field4 = B.field4
where A.key in (select key from A)
附:
删除索引:drop INDEX field1_Index ON `A`;
查看索引:show index from A
查看线程:select * from information_schema.processlist t
show processlist
杀线程: kill processId