SQL中exists和in的用法以及區別


一、in 用法

in 語法為:

select *
from table_name
where col_name in (value1, value2,...);

in 操作符允許在 where 子句中規定多個值。

in 查詢相當於多個 or 條件的疊加,比較好理解。

in 查詢就是先將子查詢條件的記錄全都查出來。

in 查詢的子條件返回結果必須只有一個字段。

二、exists 用法

exists 語法為:

select *
from table_a a
where exists (select 1 from table_b b where b.id = b.id);

exists 對外表用 loop 逐條查詢,每次查詢都會查看 exists 的條件語句。

exists 里的條件語句能夠返回記錄行時(無論返回多少記錄行,只要能返回),條件就為真,返回當前 loop 到的這條記錄。

反之如果 exists 里的條件語句不能返回記錄行,則當前 loop 到的這條記錄被丟棄。

exists 的條件就像一個 bool 條件,當能返回結果集則為 true,不能返回結果集則為 false

當子查詢為 select NULL 時, mysql 仍然認為它是 True

三、in 與 exists 的區別

in 語句:只執行一次

確定給定的值是否與子查詢或列表中的值相匹配。

in 在查詢的時候,首先查詢子查詢的表,然后將內表和外表做一個笛卡爾積,然后按照條件進行篩選。

所以相對內表比較小的時候,in 的速度較快。

exists 語句:執行n次(外表行數)

指定一個子查詢,檢測行的存在。

遍歷循環外表,檢查外表中的記錄有沒有和內表的的數據一致的。

匹配得上就放入結果集。

區別和應用場景

inexists 的區別: 如果子查詢得出的結果集記錄較少,主查詢中的表較大且又有索引時應該用 in, 反之如果外層的主查詢記錄較少,子查詢中的表大,又有索引時使用 exists

其實我們區分 inexists 主要是造成了驅動順序的改變(這是性能變化的關鍵),如果是 exists,那么以外層表為驅動表,先被訪問,如果是 in ,那么先執行子查詢,所以我們會以驅動表的快速返回為目標,那么就會考慮到索引及結果集的關系 ,另外 in 是不對 NULL 進行處理。

in 是把外表和內表作 hash 連接,而 exists 是對外表作 loop 循環,每次 loop 循環再對內表進行查詢。一直以來認為 existsin 效率高的說法是不准確的。

not in 和 not exists

如果查詢語句使用 not in,那么內外表都進行全表掃描,沒有用到索引;

not exists 的子查詢依然能用到表上的索引。所以無論那個表大,用 not exists 都比not in 要快。

四、結論

1. 外層查詢表小於子查詢表,則用 exists,外層查詢表大於子查詢表,則用 in ,如果外層和子查詢表差不多,則愛用哪個用哪個。

2.not exists 比 not in 效率高。

in 的遍歷是在內存中遍歷。

exists 需要查詢數據庫。

查詢數據庫所消耗的性能更高,而內存比較快。

參考鏈接1:在MySQL里,有個和in一樣的東東叫做exists,但是它比in更牛叉,你會么?

參考鏈接2:淺析MySQL中exists與in的使用 (寫的非常好)

參考鏈接3:Sql 語句中 IN 和 EXISTS 的區別及應用


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM