MySQL中in和=的區別
今天碰到一個關於資料庫查詢的效能問題,平常加一句索引也就過去了,今天多說兩句。
前置條件:MySQL資料庫,uid是主鍵,login_name未建任何索引, T_USER表中資料有8451條;
分別執行下列兩句SQL
1) SELECT * FROM T_USER WHERE uid IN (SELECT MIN(uid) FROM T_USER WHERE login_name =#{loginName})
2) SELECT * FROM T_USER WHERE uid = (SELECT MIN(uid) FROM T_USER WHERE login_name =#{loginName})
結果發現第一句執行的效率非常差,幾乎把資料庫掛起,第二句就好很多。
為什麼會是這個結果呢,通過檢視執行計劃如下:
Explain SELECT * FROM T_USER WHERE uid IN (SELECT MIN(uid) FROM T_USER WHERE login_name =#{loginName})
IN 查詢作了兩次全表掃描,相當於做了8451*8451條記錄的查詢;
Explain SELECT * FROM T_USER WHERE uid = (SELECT MIN(uid) FROM T_USER WHERE login_name =#{loginName})
=查詢很快將 primary查詢的次數給降了下來
給login_name增加索引 後,執行
Explain SELECT * FROM T_USER WHERE uid IN (SELECT MIN(uid) FROM T_USER WHERE login_name =#{loginName})
做了索引後,子查詢的次數明顯降下來,但主查詢還是不變
Explain SELECT * FROM T_USER WHERE uid = (SELECT MIN(uid) FROM T_USER WHERE login_name =#{loginName})
查詢的效能進一步優化。
結論:因為查詢次數並不會隨著IN欄位是否有索引而減少,所以應儘量避免使用IN查詢;增加子查詢欄位的索引將極大的減少查詢次數。