Mysql中EXISTS關鍵字用法、總結


 在做教務系統的時候,一個學生(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 的語句執行。執行的結果當然就是一樣的了。

 

 


免責聲明!

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



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