在做教務系統的時候,一個學生(alumni_info)有多個教育經歷(alumni_education),使用的數據庫是mysql,之前使用左鏈接查詢的,發現數據量才只有幾萬條時,查詢就很慢了,早上想到用子查詢in,感覺效率還不是很高,結果想到用exists,效率高了很多。由於是第一次在mysql中使用exists,百度了一番,現將自己的總結如下:
1、exists的返回結果是bool型,只有true或者false
如 SELECT * FROM alumni_info t WHERE EXISTS(SELECT a_id FROM alumni_education e WHERE e.a_id='6588' ),返回的結果跟SELECT * FROM alumni_info t一樣(a_id=6588存在),因為select語句先執行where條件后的語句,再篩選字段,當執行完where條件后,若這條結果集存在,則where表達式后面永遠都是true,否則為false。也就是說要么查詢所有,要么沒有數據。那么我只想查校友id,為6588的校友,使用exists該怎么寫,經過一番測試,內查詢中的id,必須為外查詢的id,即SELECT * FROM alumni_info t WHERE EXISTS(SELECT a_id FROM alumni_education e WHERE t.id_='6588' ),ok,完事.
2、如果我想查詢所有教育經歷的校友,使用exists實現,當然用in實現也一樣,不過效率低點
SELECT * FROM alumni_info t WHERE EXISTS(SELECT a_id FROM alumni_education e WHERE e.a_id=t.ID_ )
3、exists的效率比in查詢要高,因為IN不走索引,但要看實際情況具體使用,IN適合於外表數據量大而內表數據小的情況;EXISTS適合於外表小而內表大的情況
4、exists與not exists是想對應的。
這條語句適用於a表比b表大的情況
select * from ecs_goods a where cat_id in(select cat_id from ecs_category);
這條語句適用於b表比a表大的情況
select * from ecs_goods a where EXISTS(select cat_id from ecs_category b where a.cat_id = b.cat_id);
在MySQL中 EXISTS 和 IN 的用法有什么關系和區別呢?
假定數據庫中有兩個表 分別為 表 a 和表 b
create table a
(
a_id int,
a_name varchar(20)
)
create table b
(
b_id int,
b_name varchar(20)
)
那么
select * from a where a_name in (select b_name from b)
這條SQL語句的意義很明顯是選取滿足where條件下 a 中的所有列的數據 。而where條件就是a_name要是所有b_name的其中的一個。
即 假設 b 中的 b_name 有 {'john','peter','baron'} 這些,而a中的某條數據中的a_name恰好是其中一個,那么這行數據就會被選取出來。
而使用EXISTS:
select * from a where exists (select b_id from b where b.b_name=a.a_name)
執行的結果與上面使用 in 返回的結果是一樣的。
那么為什么會這樣呢,子查詢中 返回的列是 b_id ,並沒有 name啊。
原因就是exists子句返回的結果並不是從數據庫中取出的結果集,而是一個布爾值,如果子句查詢到數據,那么返回true,反之返回false。
所以子句中選擇的列根本就不重要,而重要的是where 后的條件。如果返回了true,那么相當於直接執行了子句 where 后的部分,即把
a_name 和 b_name 作比較,如果相等則返回這條數據。所以執行的結果和前面使用 in 的返回的結果是一致的。
有趣的是,MySQL內部優化器會把第一條使用 in 的語句轉化為第二條使用 exists 的語句執行。執行的結果當然就是一樣的了。
