创建两张表先单独插入两条数据

 然后批量插入部门号为10,20,30,40的数据各10499099条

 然后dept表也插些干扰数据

 测试语句

 开始验证in和exists和join
 先比较个占比多的部门,再比较占比少的
 1、 in 占比多
 select count(*) from scott.EMP_TEST e where e.deptno in (select d.deptno from scott.DEPT_TEST d where d.dname='SALES') ;



 跟真实执行计划基本一样,所以之后的都用autotrace来看
 2.exists 占比多
 select count(*) from scott.EMP_TEST e where exists (select d.deptno from scott.DEPT_TEST d where d.dname='SALES' and e.deptno=d.deptno) ;

 3.join 占比多
 select count(*) from scott.EMP_TEST e inner join scott.DEPT_TEST d on e.deptno=d.deptno and d.dname='SALES' ;

http://4.in 占比少
 select count(*) from scott.EMP_TEST e where e.deptno in (select d.deptno from scott.DEPT_TEST d where d.dname='TEST') ;

 5.exists 占比少
 select count(*) from scott.EMP_TEST e where exists (select d.deptno from scott.DEPT_TEST d where d.dname='TEST' and e.deptno=d.deptno) ;

 6.join 占比少
 select count(*) from scott.EMP_TEST e inner join scott.DEPT_TEST d on e.deptno=d.deptno and d.dname='TEST' ;

 7.not in 占比多
 select count(*) from scott.EMP_TEST e where e.deptno not in (select d.deptno from scott.DEPT_TEST d where d.dname<>'SALES') ;

 8.not exists 占比多
 select count(*) from scott.EMP_TEST e where not exists (select d.deptno from scott.DEPT_TEST d where d.dname<>'SALES' and e.deptno=d.deptno) ;

 9.join 占比多
 select count(*) from scott.EMP_TEST e left join scott.DEPT_TEST d on e.deptno=d.deptno and d.dname<>'SALES' where d.deptno is null ;

 10.not in 占比少
 select count(*) from scott.EMP_TEST e where e.deptno not in (select d.deptno from scott.DEPT_TEST d where d.dname<>'TEST') ;

 11. not exists 占比少
 select count(*) from scott.EMP_TEST e where not exists (select d.deptno from scott.DEPT_TEST d where d.dname<>'TEST' and e.deptno=d.deptno) ;

 12. join 占比少
 select count(*) from scott.EMP_TEST e left join scott.DEPT_TEST d on e.deptno=d.deptno and d.dname<>'TEST' where d.deptno is null ;

 下面创建两个简单索引来测试下

 1、 in 占比多
 select count(*) from scott.EMP_TEST e where e.deptno in (select d.deptno from scott.DEPT_TEST d where d.dname='SALES') ;

 分析不走索引的原因是因为统计信息不全,收集下统计信息

 2.exists 占比多
 select count(*) from scott.EMP_TEST e where exists (select d.deptno from scott.DEPT_TEST d where d.dname='SALES' and e.deptno=d.deptno) ;

 3.join 占比多
 select count(*) from scott.EMP_TEST e inner join scott.DEPT_TEST d on e.deptno=d.deptno and d.dname='SALES' ;

http://4.in 占比少
 select count(*) from scott.EMP_TEST e where e.deptno in (select d.deptno from scott.DEPT_TEST d where d.dname='TEST') ;

 5.exists 占比少
 select count(*) from scott.EMP_TEST e where exists (select d.deptno from scott.DEPT_TEST d where d.dname='TEST' and e.deptno=d.deptno) ;

 6.join 占比少
 select count(*) from scott.EMP_TEST e inner join scott.DEPT_TEST d on e.deptno=d.deptno and d.dname='TEST' ;

 7.not in 占比多
 select count(*) from scott.EMP_TEST e where e.deptno not in (select d.deptno from scott.DEPT_TEST d where d.dname<>'SALES') ;

 8.not exists 占比多
 select count(*) from scott.EMP_TEST e where not exists (select d.deptno from scott.DEPT_TEST d where d.dname<>'SALES' and e.deptno=d.deptno) ;

 9.join 占比多
 select count(*) from scott.EMP_TEST e left join scott.DEPT_TEST d on e.deptno=d.deptno and d.dname<>'SALES' where d.deptno is null ;

 10.not in 占比少
 select count(*) from scott.EMP_TEST e where e.deptno not in (select d.deptno from scott.DEPT_TEST d where d.dname<>'TEST') ;

 11. not exists 占比少
 select count(*) from scott.EMP_TEST e where not exists (select d.deptno from scott.DEPT_TEST d where d.dname<>'TEST' and e.deptno=d.deptno) ;

 12. join 占比少
 select count(*) from scott.EMP_TEST e left join scott.DEPT_TEST d on e.deptno=d.deptno and d.dname<>'TEST' where d.deptno is null ;

 在简单比较下时间




可以看出在相同条件下,执行计划是相同的,时间消耗也是一样的
因为有朋友说not exists的子查询会走索引not in索引失效,所以not exists会快,所以为了说服他又做了点补充









并没有什么差别。而且not in和not exists都会使索引失效,但是不影响子查询的索引使用!!!!所以直接说谁比谁快的都是不负责任的说法,还是要具体情况具体分析。分情况使用。那些说not exists比not in快的,这种情况很多,因为不同的原因造成他们的sql的执行计划不同了,所以效率也不同了
抛开执行计划和实际情景,不考虑数据情况,数据量、索引情况甚至统计信息等这些因素,直接说哪一种比较快都是不靠谱的