in是把外表和內表做hash鏈接,而exists是對外表做loop循環,每次loop循環一次對內表進行一次查詢。
若是查詢的兩個表大小至關,那麼用in和exists差異不大;若是兩個表中一個較小一個較大,則子查詢表大的用exists,子查詢表小的用in;mysql
注意: A表與B表的id字段應創建索引sql
select * from A where id in (select id from B) // in會使用子查詢結果去主表匹配須要的行。子查詢結果越大,去主表索引(A表上id列的索引)中檢索的次數越多,效率越低
等價於:oop
for select id from B for select * from A where A.id = B.id // 好比:A表有5條記錄,B表裏有4萬條記錄,in會循環用4萬個數據(id)去匹配這5條記錄,成本遠比用5條數據(id)去匹配4萬條記錄效率低
select * from A where exists (select 1 from B where B.id = A.id) // exists是根據匹配項去判斷是或者否,而後根據是否決定結果,子查詢的表大,用exists判斷,效率就會高
等價於性能
for select * from A for select * from B where B.id = A.id //好比:A表有5條記錄,B表裏有4萬條記錄,exists只進行5次判斷,比in快不少。
結論:當A表的數據集小於B表的數據集時,用exists優於in。測試
select * from A where id in(select id from B) //效率高 select * from A where exists(select cc from B where cc=A.id) //效率低
結論:當B表的數據集小於A表的數據集時,用in優於exists。優化
not in 和not exists若是查詢語句使用了not in 那麼內外表都進行全表掃描,沒有用到索引;而not extsts 的子查詢依然能用到表上的索引。因此不管那個表大,用not exists都比not in要快。spa
網上還有人說mysql5.6版本對in查詢作了很好的優化,因此效率問題要看具體的場景,要看真實測試的數據來進行優化!code
若是in和or所在列有索引或者主鍵的話,or和in沒啥差異,執行計劃和執行時間都幾乎同樣。索引
若是in和or所在列沒有索引的話,性能差異就很大了。在沒有索引的狀況下,隨着in或者or後面的數據量越多,in的效率不會有太大的降低,可是or會隨着記錄越多的話性能降低很是厲害。hash
所以在給in和or的效率下定義的時候,應該再加上一個條件,就是所在的列是否有索引或者是不是主鍵。若是有索引或者主鍵性能沒啥差異,若是沒有索引,性能差異不是一點點!