1. 程式人生 > >乾貨:MySQL效能優化,in和exists

乾貨:MySQL效能優化,in和exists

乾貨:MySQL效能優化,in和exists

 

in和exists哪個效能更優

sql指令碼:

乾貨:MySQL效能優化,in和exists

 

上面的sql中 訂單表中(orders) 存在user_id,而又有使用者表(users),所以我們用orders表中user_id和user表中的id 來in 和 exists。

結果

1.where後面是小表

(1)select count(1) from orders o where o.user_id in(select u.id from users u);

乾貨:MySQL效能優化,in和exists

 

(2)select count(1) from orders o where exists (select 1 from users u where u.id = o.user_id);

乾貨:MySQL效能優化,in和exists

 

2.where後面是大表

(1)select count(1) from users u where u.id in (select o.user_id from orders o);

乾貨:MySQL效能優化,in和exists

 

(2)select count(1) from users u where exists (select 1 from orders o where o.user_id = u.id);

乾貨:MySQL效能優化,in和exists

 

分析

我們用下面的這兩條語句分析:

select count(1) from orders o where o.user_id in(select u.id from users u); select count(1) from orders o where exists (select 1 from users u where u.id = o.user_id);

1.in:先查詢in後面的users表,然後再去orders中過濾,也就是先執行子查詢,結果出來後,再遍歷主查詢,遍歷主查詢是根據user_id和id相等查詢的。

即查詢users表相當於外層迴圈,主查詢就是外層迴圈

小結:in先執行子查詢,也就是in()所包含的語句。子查詢查詢出資料以後,將前面的查詢分為n次普通查詢(n表示在子查詢中返回的資料行數)

2.exists:主查詢是內層迴圈,先查詢出orders,查詢orders就是外層迴圈,然後會判斷是不是存在order_id和 users表中的id相等,相等才保留資料,查詢users表就是內層迴圈

這裡所說的外層迴圈和內層迴圈就是我們所說的巢狀迴圈,而巢狀迴圈應該遵循“外小內大”的原則,這就好比你複製很多個小檔案和複製幾個大檔案的區別

小結:如果子查詢查到資料,就返回布林值true;如果沒有,就返回布林值false。返回布林值true則將該條資料儲存下來,否則就捨棄掉。也就是說exists查詢,是查詢出一條資料就執行一次子查詢

結論

小表驅動大表。

in適合於外表大而內表小的情況,exists適合於外表小而