create table #t1(c1 int,c2 int);
create table #t2(c1 int,c2 int);
insert into #t1 values(1,2);
insert into #t1 values(1,3);
insert into #t2 values(1,2);
insert into #t2 values(1,null);
select * from #t1 where c2 not in(select c2 from #t2); -->执行结果:无
select * from #t1 where not exists(select 1 from #t2 where #t2.c2=#t1.c2) -->执行结果:1 3
如果 NOT IN 子查询中返回的任意一条记录含有空值,则查询将不返回任何记录。如果子查询字段有非空限制,这时可以使用 NOT IN,并且可以通过提示让它使用索引。
IN 是把外表和内表作 hash 连接,而 EXISTS 是对外表作 loop 循环,每次 loop 循环再对内表进行查询,一直以来认为 EXISTS 比 IN 效率高的说法是不准确的。如果查询的两个表大小相当,那么用 IN 和 EXISTS 差别不大;如果两个表中一个较小一个较大,则子查询表大的用 EXISTS,子查询表小的用 IN。