【Mysql】關(guān)于索引
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
無引擎時(shí):每1000更新需要2分11秒,全部更新大概需要2~3小時(shí)。
此時(shí)加入索引:
CREATE INDEX field1_Index ON `A`(`field1`);
注:1、此處只加field1是因?yàn)?field2的內(nèi)容變化很小,就那幾個(gè)值。
2、此SQL里的字段都不是主鍵
注:1、此處只加field1是因?yàn)?field2的內(nèi)容變化很小,就那幾個(gè)值。
2、此SQL里的字段都不是主鍵
再次執(zhí)行SQL,效率依舊。似乎索引沒有作用。為了驗(yàn)證我的想法,查看了執(zhí)行方式:
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
果然在執(zhí)行時(shí),沒用到索引。找到癥結(jié),那就繼續(xù)找為什么索引沒有被用的原因。查找過程省略,直接上結(jié)果。
因?yàn)槭莡pdate,所以我認(rèn)為 左聯(lián)和直聯(lián),對于結(jié)果沒有區(qū)別,但是從左聯(lián)改為直聯(lián)后,
再查詢執(zhí)行方式,發(fā)現(xiàn)就能使用索引(原因暫不知道,以后知道了再寫)
于是再次執(zhí)行如下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
優(yōu)化完畢。
另,因?yàn)橐陨献侄味挤侵麈I,所以 SQL修改成以下方式執(zhí)行似乎更快,查詢執(zhí)行方式,用到了主鍵索引和我自己加的索引
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)set A.field3 = B.field3, A.field4 = B.field4
附:
刪除索引:drop INDEX field1_Index ON `A`;
查看索引:show index from A
查看線程:select * from information_schema.processlist t
show processlist
殺線程: kill processId