為了大家學習方便,我在這裡程式設計客棧面建立兩張表並為其新增一些資料。
一張水果表,一張**商表。
水果表 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...