Mysql優化原則_小表驅動大表IN和EXISTS的合理利用

//假設一個for循環
for($i = 0; $i < 10000; $i++) 
{
     for ($j = 0; $i < 50; $j++)
     {

     }
}

for($i = 0; $i < 50; $i++) 
{
    for ($j = 0; $i < 10000; $j++)
    {

    }
}

看以上兩個for循環,總共循環的次數是同樣的。可是對於mysql數據庫而言,並非這樣了,咱們儘可能選擇第②個for循環,也就是小表驅動大表。
數據庫最傷神的就是跟程序連接釋放,第一個創建了10000次連接,第二個創建了50次。假設連接了兩次,每次作上百萬次的數據集查詢,查完就走,這樣就只作了兩次;相反創建了上百萬次連接,申請連接釋放反覆重複,這樣系統就受不了了。
這時候就誕生了in 和exists的對比。mysql

小表驅動大表:即小的數據集驅動大的數據集。sql

這裏假設A表表明員工表,B表表明部門表。
假設部門只有三個,銷售、技術部、行政部,言下之意是在這三個部門裏的全部員工都查出。數據庫

select * from A where id in (select id from B);

這樣寫就等價於:
for select id from B。好比華爲有100個部門,可是華爲的員工少說有15W-20W,員工總比部門多,這時候就至關於獲得了小表(部門表);for select * from A where A.id = B.id,至關於A.id等B表裏面的,至關於從部門表得到對應的id。優化

當B表的數據集必須小於A表的數據集時,用in優於exists。
反之code

select * from A where exists (select 1 from B where B.id = A.id); //這裏的select 1並不絕對,能夠寫爲select 'X'或者'A','B','C'均可以,只要是常量就能夠。

這樣寫就等價於:
for select * from A,先從A表作循環
for select * from B where B.id = A.id,再從B表作循環。
這樣exists就會變成看看A表是否存在於(select 1 from B where B.id = A.id)裏面,這個查詢返回的是TRUE或者FALSE的BOOL值,簡單來講就是要當A表的數據集小於B表的數據集時,用exists優於in。要注意的是:A表與B表的ID字段應該創建索引。索引

語法:EXISTSfor循環

SELECT ...FROM table WHERE EXISTS(subquery)。
理解:將主查詢的數據放到子查詢中作條件驗證,根據驗證結果(TRUE或者FALSE)來決定朱查詢的數據結果是否得意保留。
至關於從表A和B中取出交集,而後再從A表中取出所在交集的部分數據,固然後面加WHERE條件還能夠進一步篩選。table

補充效率

1:EXISTS(subquery)只返回TRUE或者FALSE,所以子查詢中的SELECT * 也能夠是SELECT 1或者SELECT 'X',官方說法是實際執行時會忽略SELECT清單,所以沒有區別。
2:EXISTS子查詢的實際執行過程可能通過了優化而不是咱們理解上的逐條對比,若是擔心效率問題,可進行實際校驗。
3:EXISTS子查詢旺旺能夠用條件表達式,其餘子查詢或者JOIN來替代,何種最優須要具體問題具體分析。select

若是查詢的兩個表大小至關,那麼用in和exists差異不大。

延伸舉例鞏固

若是兩個表中一個較小,一個是大表,則子查詢表大的用exists,子查詢表小的用in:
例如:表A(小表),表B(大表)

select * from A where cc in (select cc from B) ;//  效率低,用到了A表上cc列的索引;
select * from A where exists(select cc from B where cc=A.cc) ;// 效率高,用到了B表上cc列的索引。

相反

select * from B where cc in (select cc from A) ; //效率高,用到了B表上cc列的索引;
select * from B where exists(select cc from A where cc=B.cc) ;//效率低,用到了A表上cc列的索引。

not in 和not exists若是查詢語句使用了not in 那麼內外表都進行全表掃描,沒有用到索引;而not extsts 的子查詢依然能用到表上的索引。因此不管那個表大,用not exists都比not in要快。

相關文章
相關標籤/搜索