前言
在面試談到sql優化的一些經驗時,有些面試者會回答:寫sql時,最好用exists來代替in,因為in不走索引,是以用exists的sql性能較好,那真的是這樣麼?
以下用AB兩表,做個示例,兩表都有一個id字段,而兩個表都為id字段建立了索引
In
in的作用其實就是把範圍記憶體在的資料做個傳回,先看看下圖的簡單示例sql:
select * from A where id in (select id from B)
這句sql等價于兩個循環:
for select id from B
for select * from A where A.id = B.id
其實就是對B表的id做個外層循環,而内層再嵌套一層A表的id循環,内層循環裡判斷A表和B表的id是否相等,相等的話就是要傳回的資料。
Exists
exists的作用就是把主查詢的資料,放到自查詢中做條件的驗證,結果是true則保留主查詢中的結果,為false則不保留,以下用exists實作和in一樣的效果:
select * from A where exists(select * from B where B.id = A.id)
這句sql也等價于兩個循環:
for select * from A
for select * from B where B.id = A.id
其實就是對A表的id做個外層循環,而内層再嵌套一層B表的id循環,内層循環裡判斷B表和A表的id是否相等,相等的話就是要傳回的資料。
這時引申出一個sql優化的規則:以小表驅動大表,mysql連接配接數會更少,sql性能會更佳
分析下,用in時,是in裡面的表驅動外面的表,是以如果B表相對于A表是小表,用in比較好。而用exists時,是外面的表驅動exists裡面的表,是以如果A表相對于B表是小表,則用exists比較好。
總結
明白了
IN
和
EXISTS
的原理後,配合上小表驅動大表的優化規則,可以得出用
EXISTS
或者是用
IN
,還需要根據表中資料情況而定。
IN
适合于外表大而内表小的情況,而
EXISTS
适合于外表小而内表大的情況。
select * from user where id in(1,2,3)