not in 与not exists 区别、以及效率分析

not in 与not exists 区别、以及效率分析因为 notin 和 notexists 涉及到子查询和关联子查询 所以先了解一下子查询和关联子查询以及它们之间的区别 notin 和 notexit

大家好,欢迎来到IT知识分享网。

前言

因为 not in 和 not exists 涉及到子查询和关联子查询,所以先了解一下子查询和关联子查询以及它们之间的区别

子查询与关联子查询

子查询

非相关子查询是独立于外部查询的子查询,子查询执行完毕后将值传递给外部查询

 select * from emp where sal = (select max(sal) from emp); 

执行逻辑:

  1. 先执行内层 sql
  2. 后执行外层 sql

关联子查询

在关联子查询中,对于外部查询返回的每一行数据,内部查询都要执行一次。另外,在关联子查询中是信息流是双向的。外部查询的每行数据传递一个值给子查询,然后子查询为每一行数据执行一次并返回它的记录。然后,外部查询根据返回的记录做出决策。

select * from dept d where exists(select * from emp e where e.deptno = d.deptno); 

执行逻辑

  1. 先执行外层 sql
  2. 后执行内层 sql

在这里插入图片描述

测试案例1 not in 与 not exits 速度对比

本质上考察子查询与关联查询的速度对比

创建表

create table A( a varchar2(10), b varchar2(10), c varchar2(10) ); create table B( a varchar2(10), b varchar2(10) ); truncate table A; truncate table B; select * from A; select * from B; 

生成测试数据

begin for i in 0 ..  loop if mod(i, 2) = 0 then insert into A values(i, i+2, i); else insert into A values(i, i, i); end if; insert into B values(i, i); end loop; commit; end; 

Tips: mod(被除数, 除数) 作用: 取余

查询数据

-- not exists 方式 select c from a where not exists( select c from b where (a.a = b.a and a.b = b.b) ) select c from a where not exists( select 1 from b where (a.a = b.a and a.b = b.b) ) -- not in 方式 select c from a where c not in ( select c from a join b on (a.a = b.a and a.b = b.b) ) 

在这里插入图片描述


测试案例2- not in 存在逻辑问题

not in 采用子查询
not exits 采用关联子查询
truncate table t1; truncate table t2; 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); commit; 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 exists 执行计划分析

在这里插入图片描述

not in 执行计划分析

image.png

not in 和 not exists 执行逻辑

-- 执行逻辑: not in  for i in (select * from t1) loop for j in( select * from t2) loop if( t1[c2] != t2[c2]) then output_record end if; end loop; end loop; -- 执行逻辑: not exists for i in (select * from t1) loop if( not exists(select 1 from t1 where t2.c2 = t1.i[c2])) then output_record end if end loop; 

总结:如果查询语句使用了not in,那么对内外表都进行全表扫描,没有用到索引;而not exists的子查询依然能用到表上的索引。所以无论哪个表大,用not exists都比not in 要快。

not in 不对 null 做处理

select 1 from dual where null in (0,1,2,null) 

参考

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/125965.html

(0)
上一篇 2025-09-22 18:33
下一篇 2025-09-22 19:00

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信