MySQL之in與exists

541732025發表於2014-05-30
mysql最佳化器對in語句的最佳化是“LAZY”的,對於in,如果不是顯示的列表定義,如in('a','b','c'),那麼in語句都會被轉換為exists相關子查詢。如下面獨立子查詢:
select ...from t1 where t1.a in (selelct b from t2);
最佳化器會將語句重寫為如下相關子查詢:
select ...from t1 where exists (select 1 from t2 where t2.b = t1.a)

如果t1,t2分別返回m、n行,那麼該查詢掃描為o(n+m*n)次,首先,exists需要掃描n次,然後相關查詢是m*n次維度的。
所以,我們不要花費精力去想到底是用in還是exists,因為mysql最佳化器會自動轉換,我們應該花時間來降低表的邏輯IO
怎樣降低掃描次數?在不能改變t1的返回結果時,只能考慮最佳化子查詢了了。
譬如1:子查詢中如果有group by操作,那麼每一次關聯外部查詢,都會進行一次group by,共進行n次group by操作,
所以可以考慮在相關子查詢外面再巢狀一層子查詢,做成靜態的,這樣就不用每次關聯查詢都去group by了。
2,對子查詢建立索引,也能減少邏輯IO
3,可以使用派生表(臨時表)重寫子查詢,進行表連線,以避免子查詢與外部查詢進行多次比較。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28912557/viewspace-1173059/,如需轉載,請註明出處,否則將追究法律責任。

相關文章