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

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

 

in和exists哪一個性能更優sql

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);spa

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

 

2.where後面是大表blog

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

乾貨: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相等查詢的。im

即查詢users表至關於外層循環,主查詢就是外層循環

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

2.exists:主查詢是內層循環,先查詢出orders,查詢orders就是外層循環,而後會判斷是否是存在order_id和 users表中的id相等,相等才保留數據,查詢users表就是內層循環

這裏所說的外層循環和內層循環就是咱們所說的嵌套循環,而嵌套循環應該遵循「外小內大」的原則,這就比如你複製不少個小文件和複製幾個大文件的區別

小結:若是子查詢查到數據,就返回布爾值true;若是沒有,就返回布爾值false。返回布爾值true則將該條數據保存下來,不然就捨棄掉。也就是說exists查詢,是查詢出一條數據就執行一次子查詢

結論

小表驅動大表。

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

相關文章
相關標籤/搜索