目前負責的一個項目,需要維護一個電話號碼對比庫,表名為phone_bak1,以下稱為a表,量級為3000萬條。還有另外一張表存儲電話白名單,表名為phone_delete,以下稱為b表,量級為3000條左右。 目的呢,是要從a表中排除掉在b表中的電話號碼。 我直接使用以下語句: DELETE FRO ...
目前負責的一個項目,需要維護一個電話號碼對比庫,表名為phone_bak1,以下稱為a表,量級為3000萬條。還有另外一張表存儲電話白名單,表名為phone_delete,以下稱為b表,量級為3000條左右。
目的呢,是要從a表中排除掉在b表中的電話號碼。
我直接使用以下語句:
DELETE FROM phone_bak1 WHERE phone IN (SELECT phone FROM phone_delete)
然後phpMyAdmin直接就報超時了。雖然超時了但是語句還是執行了,當時沒多想,就沒管,今天就拿到研究研究。加上EXPLAIN分析sql語句:
EXPLAIN DELETE FROM phone_bak1 WHERE phone IN (SELECT phone FROM phone_delete)
可以看到並沒有走索引,而是遍歷了a表,所以執行時間會很長,難道是where in 不會走索引?帶著這樣的疑惑,我嘗試了查詢語句:
EXPLAIN SELECT * FROM phone_bak1 WHERE phone IN (SELECT phone FROM phone_delete)
很明顯,where in 是會走索引的,但是在delete中使用不會使用索引。在網上查詢了下資料,看到有人說使用inner join mysql會走索引,於是我嘗試了下,使用以下sql語句:
EXPLAIN DELETE phone_bak1 FROM phone_bak1 INNER JOIN phone_delete ON phone_bak1.phone = phone_delete.phone
可以看到使用inner join 確實走了索引,今天發現這個問題覺得還是挺有意思的,把它記錄下來,希望自己以後在項目中不要犯這種錯誤