MySQL中in和exists區別詳解

2022-09-24 11:21:12 字數 1892 閱讀 6431

為了大家學習方便,我在這裡程式設計客棧面建立兩張表並為其新增一些資料。

一張水果表,一張**商表。

水果表 fruits表

f_id

f_name

f_price

a1apple5a2

appricot2b1

blackberry

10b2

berry8c1

cocount

9**商表 suppliers表

s_id

s_name

101天虹

102沃爾瑪

103家樂福

104華潤萬家

我們將用這兩張表做演示。

exists關鍵字後面的引數是乙個任意的子查詢,系統對子查詢進行運算以判斷它是否返回行,如果至少返回一行,那麼exists的結果為true,此時外層的查詢語句將進行查詢;如果子查詢沒有返回任何行,那麼exists的結果為false,此時外層語句將不進行查詢。

需要注意的是,當我們的子查詢為select null時,mysql仍然認為它是true。

in 關鍵字進行子查詢時,內層查詢語句僅僅返回乙個資料列,這個資料列的值將提供給外層查詢語句進行比較操作。

為了測試in 關鍵字,我在水果表中加了s_id一列

水果表 fruits表

f_id

f_name

f_price

s_id

a1apple

5101

a2appricot

2103

b1blackberry

10102

vnetuaw b2

berry

8104

c1cocount

9103

in和exists到底有啥區別那,要什麼時候用in,什麼時候用exists?

我們先記住口訣再說細節!「外層查詢表小於子查詢表,則用exists,外層查詢表大於子查詢表,則用in,如果外層和子查詢表差不多,則愛用哪個用哪個。」

我想你已經看出來了,當fruits表資料很大的時候不適合用in,因為它最多會將fruits表資料全部遍歷一次。

如:suppliers表有10000條記錄,fruits表有1000000條記錄,那麼最多有可能遍歷10000*1000000次,效率很差。

再如:suppliers表有10000條記錄,fruits表有100條記錄,那麼最多有可能遍歷10000*100次,遍歷次數大大減少,效率大大提公升。

但是:suppliers表有10000條記錄,fruits表有100條記錄,那麼exists()還是執行10000次,還不如使用in()遍歷10000*100次,因為in()是在記憶體裡遍歷,而exists()需要查詢資料庫,我們都知道查詢資料庫所消耗的效能更高,而記憶體比較很快。

因此我們只需要記住口訣:「外層查詢表小於子查詢表,則用exists,外層查詢表大於子查詢表,則用in,如果外層和子查詢表差不多,則愛用哪個用哪個。」

和exists一樣,用到了suppliers上的id索引,exists()執行次數為fruits.length,不快取exists()的結果集。

因為not in實質上等於!= and !=,因為!=不會使用索引,故not in不會使用索引。

我們假設有100萬資料,s_id只有0和1兩個值,利用索引我們要先讀索引檔案,然後二分查詢,找到對應的資料磁碟指標,再根據讀到的指標在磁碟上對應的資料,影響結果集50萬,這種情況,和直接全表掃瞄哪個快顯而易見。

如果你s_id欄位是乙個unique,就會用到索引。

如果你一定要用索引,可以用force index,不過效率不會有改善一般還會更慢就是了。

合理使用索引,cardinality是乙個重要指標,太小的話跟沒建沒區別,還浪費空間。

因此,不管suppliers和fruits大小如何,均使用not exists效率會更高。

MySql中in和exists效率

詳見 mysql中的in語句是把外表和內錶作hash 連線,而exists語句是對外表作loop迴圈,每次loop迴圈再對內表進行查詢。一直大家都認為exists比in語句的效率要高,這種說法其實是不準確的。這個是要區分環境的。如果查詢的兩個表大小相當,那麼用in和exists差別不大。如果兩個表中...

MySQL中的in和exists區別

in和exists的區別分析 select from a where id in select id from b select from a where exists select 1from b where a.id b.id 對於以上兩種情況,in是在記憶體裡遍歷比較,而exists需要查詢資...

MySQL中 in和exists的區別

a表 100條資料 b 10條資料 select from a where id in select aid from b 先執行括號裡面的查詢,然後執行外面,總共需要查詢的次數的 b 1 11次 需要注意的是 括號裡面的查詢會快取到記憶體中 select from a where exists s...