肯定給定的值是否與子查詢或列表中的值相匹配。in在查詢的時候,首先查詢子查詢的表,而後將內表和外表作一個笛卡爾積,而後按照條件進行篩選。因此相對內表比較小的時候,in的速度較快。sql
具體sql示例:oop
select * from student s where s.stuid in(select stuid from score ss where ss.stuid = s.stuid) select * from student s where s.stuid in(select stuid from score ss where ss.stuid <1005)
以上兩個語句的執行流程:性能
首先會執行from語句找出student表,而後執行 in 裏面的子查詢,再而後將查詢到的結果和原有的user表作一個笛卡爾積,再根據咱們的student.stuid IN score.stuid的條件,將結果進行篩選(既比較stuid列的值是否相等,將不相等的刪除)。最後,獲得符合條件的數據。ui
指定一個子查詢,檢測行的存在。遍歷循環外表,而後看外表中的記錄有沒有和內表的數據同樣的。匹配上就將結果放入結果集中。spa
具體示例:code
select * from student s where EXISTS(select stuid from score ss where ss.stuid = s.stuid)
這條sql語句的執行結果和上面的in的第一條執行結果是同樣的。
可是,不同的是它們的執行流程徹底不同:索引
使用exists關鍵字進行查詢的時候,首先,咱們先查詢的不是子查詢的內容,而是查咱們的主查詢的表,也就是說,咱們先執行的sql語句是:hash
select * from student s
而後,根據表的每一條記錄,執行如下語句,依次去判斷where後面的條件是否成立:class
EXISTS(select stuid from score ss where ss.stuid = s.stuid)
若是成立則返回true不成立則返回false。若是返回的是true的話,則該行結果保留,若是返回的是false的話,則刪除該行,最後將獲得的結果返回。效率
in 和 exists的區別: 若是子查詢得出的結果集記錄較少,主查詢中的表較大且又有索引時應該用in, 反之若是外層的主查詢記錄較少,子查詢中的表大,又有索引時使用exists。其實咱們區分in和exists主要是形成了驅動順序的改變(這是性能變化的關鍵),若是是exists,那麼之外層表爲驅動表,先被訪問,若是是IN,那麼先執行子查詢,因此咱們會以驅動表的快速返回爲目標,那麼就會考慮到索引及結果集的關係了 ,另外IN時不對NULL進行處理。select * from studnet where exists(select null) 等同於: select * from studnet
in 是把外表和內表做hash 鏈接,而exists是對外表做loop循環,每次loop循環再對內表進行查詢。一直以來認爲exists比in效率高的說法是不許確的。
not in 和not exists 若是查詢語句使用了not in 那麼內外表都進行全表掃描,沒有用到索引;而not extsts 的子查詢依然能用到表上的索引。因此不管那個表大,用not exists都比not in要快。