Sql語句中IN和exists的區別及應用

2022-08-25 20:30:32 字數 2672 閱讀 4169

首先,查詢中涉及到的兩個表,乙個user和乙個order表,具體表的內容如下:

user表:

order表:

確定給定的值是否與子查詢或列表中的值相匹配。in在查詢的時候,首先查詢子查詢的表,然後將內錶和外表做乙個笛卡爾積,然後按照條件進行篩選。所以相對內錶比較小的時候,in的速度較快。

具體sql語句如下:

1 select

2 *

3 from

4 `user`

5 where

6 `user`.id in (

7 select

8 `order`.user_id

9 from

10 `order`

11 )

這條語句很簡單,通過子查詢查到的user_id 的資料,去匹配user表中的id然後得到結果。該語句執行結果如下:

它的執行流程是什麼樣子的呢?讓我們一起來看一下。

首先,在資料庫內部,查詢子查詢,執行如下**:

select

`order`.user_id

from

`order`

執行完畢後,得到結果如下:

此時,將查詢到的結果和原有的user表做乙個笛卡爾積,結果如下:

此時,再根據我們的user.id in order.user_id的條件,將結果進行篩選(既比較id列和user_id 列的值是否相等,將不相等的刪除)。最後,得到兩條符合條件的資料。

指定乙個子查詢,檢測行的存在。遍歷迴圈外表,然後看外表中的記錄有沒有和內錶的資料一樣的。匹配上就將結果放入結果集中。

具體sql語句如下:

1 select

2 `user`.*

3 from

4 `user`

5 where

6 exists (

7 select

8 `order`.user_id

9 from

10 `order`

11 where

12 `user`.id = `order`.user_id

13 )

這條sql語句的執行結果和上面的in的執行結果是一樣的。

但是,不一樣的是它們的執行流程完全不一樣:

使用exists關鍵字進行查詢的時候,首先,我們先查詢的不是子查詢的內容,而是查我們的主查詢的表,也就是說,我們先執行的sql語句是:

select `user`.* from `user` 

得到的結果如下:

然後,根據表的每一條記錄,執行以下語句,依次去判斷where後面的條件是否成立:

exists (

select

`order`.user_id

from

`order`

where

`user`.id = `order`.user_id

)

如果成立則返回true不成立則返回false。如果返回的是true的話,則該行結果保留,如果返回的是false的話,則刪除該行,最後將得到的結果返回。

in 和 exists的區別: 如果子查詢得出的結果集記錄較少,主查詢中的表較大且又有索引時應該用in, 反之如果外層的主查詢記錄較少,子查詢中的表大,又有索引時使用exists。其實我們區分in和exists主要是造成了驅動順序的改變(這是效能變化的關鍵),如果是exists,那麼以外層表為驅動表,先被訪問,如果是in,那麼先執行子查詢,所以我們會以驅動表的快速返回為目標,那麼就會考慮到索引及結果集的關係了 ,另外in時不對null進行處理。

in 是把外表和內錶作hash 連線,而exists是對外表作loop迴圈,每次loop迴圈再對內表進行查詢。一直以來認為exists比in效率高的說法是不準確的。

如果查詢語句使用了not in 那麼內外表都進行全表掃瞄,沒有用到索引;而not extsts 的子查詢依然能用到表上的索引。所以無論那個表大,用not exists都比not in要快。

sql語句中的exists和in

比如在northwind資料庫中有乙個查詢為 select c.customerid,companyname from customers c where exists select orderid from orders o where o.customerid c.customerid 這裡面的...

SQL語句中IN和EXISTS的效率問題

in select from a where id in select id from b 此處select id from b只會執行一次,將所有資料快取到記憶體,然後遍歷a表中的每條資料進行判斷是否存在。exist select from a as a where exists select i...

sql語句中exists和in的區別和應用

表展示 首先,查詢中涉及到的兩個表,乙個user和乙個 order 表,具體表的內容如下 user表 order表 確定給定的值是否與子查詢或列表中的值相匹配。in在查詢的時候,首先查詢子查詢的表,然後將內錶和外表做乙個笛卡爾積,然後按照條件進行篩選。所以相對內錶比較小的時候,in的速度較快。具體s...