SQL------not in和not exists的區別

轉載自:https://www.cnblogs.com/snn0605/p/5901634.htmlhtml

sql中的in與not in,exists與not exists的區別sql

 

一、in和existsoop

in是把外表和內表做hash鏈接,而exists是對外表做loop循環,每次loop循環再對內表進行查詢,一直以來認爲exists比in效率高的說法是不許確的。若是查詢的兩個表大小至關,那麼用in和exists差異不大;若是兩個表中一個較小一個較大,則子查詢表大的用exists,post

子查詢表小的用in;this

例如:表A(小表),表B(大表)url

select * from A where cc in(select cc from B)  -->效率低,用到了A表上cc列的索引; select * from A where exists(select cc from B where cc=A.cc)  -->效率高,用到了B表上cc列的索引。

相反的:spa

1 select * from B where cc in(select cc from A)  -->效率高,用到了B表上cc列的索引 2 select * from B where exists(select cc from A where cc=B.cc)  -->效率低,用到了A表上cc列的索引。

二、not in 和not existscode

not in 邏輯上不徹底等同於not exists,若是你誤用了not in,當心你的程序存在致命的BUG,請看下面的例子:htm

複製代碼
1 create table #t1(c1 int,c2 int); 2 create table #t2(c1 int,c2 int); 3 insert into #t1 values(1,2); 4 insert into #t1 values(1,3); 5 insert into #t2 values(1,2); 6 insert into #t2 values(1,null); 7 select * from #t1 where c2 not in(select c2 from #t2);  -->執行結果:無 8 select * from #t1 where not exists(select 1 from #t2 where #t2.c2=#t1.c2)  -->執行結果:1  3
複製代碼

正如所看到的,not in出現了不指望的結果集,存在邏輯錯誤。若是看一下上述兩個select 語句的執行計劃,也會不一樣,後者使用了hash_aj,因此,請儘可能不要使用not in(它會調用子查詢),而儘可能使用not exists(它會調用關聯子查詢)。若是子查詢中返回的任意一條記錄含有空值,則查詢將不返回任何記錄。若是子查詢字段有非空限制,這時可使用not in,而且能夠經過提示讓它用hasg_aj或merge_aj鏈接。blog

若是查詢語句使用了not in,那麼對內外表都進行全表掃描,沒有用到索引;而not exists的子查詢依然能用到表上的索引。因此不管哪一個表大,用not exists都比not in 要快。

三、in 與 = 的區別

1 select name from student where name in('zhang','wang','zhao');

1 select name from student where name='zhang' or name='wang' or name='zhao'

的結果是相同的。

相關文章
相關標籤/搜索