inner join 和 exists 效率_一个in、exists、join的简单测试

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

01c79757c5e0935576d6d5b78596cd10.png


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

362aa9fc8cbfc420ce99d2a0fbe79568.png


然后dept表也插些干扰数据

cc911c171668ac70e2b3181816c44669.png


测试语句

062618b22accc48e1b8ceb6b3eb091bb.png


开始验证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') ;

d795ca7f96585012249558da01b295e1.png

b97d2c6483e7735f9eaf93eab578b55d.png

9856824f9c52a5c887f4b5ecdd3ab00b.png


跟真实执行计划基本一样,所以之后的都用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) ;

953bac4e9c47e1df78bf0298f31b8b23.png


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

efa2a6f3ef6f44a1b11ac991020f448b.png

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') ;

eb7b7b6d786a9d7f45a9a17e2b32a66d.png


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) ;

0631cbec03b17efd212d80629950d25a.png


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

28641b9d753d1cf2d1457edf0fca8ecc.png


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') ;

e0644490dd52492102166aebab6696ac.png


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) ;

47e9ca0f42ca4326c476ddc1840a4f36.png


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 ;

4cfd9ed4ca2e4efe949b984a72c22865.png


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') ;

32369b0a3c828a9ecf222e0db0d3c668.png


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) ;

5b057cd32e88bc9837259b3ea0004f6b.png


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 ;

2ff9ad4b1dfdb2a293da16321a88491a.png


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

3fa9a1853b0aaa396260354ba83b91f8.png


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') ;

9856824f9c52a5c887f4b5ecdd3ab00b.png


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

c686d3b4e22522a4546efeda1f5cba07.png


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) ;

85c204d36db70289d7498ebb002ff9b3.png


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

ee1e5c409ffa3fba4d8302489ba84bdf.png

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') ;

9dc0852db6013cec9d04c34cf560a740.png


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) ;

c32028c17f02efd142a830e0f9a7a05f.png


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

0f336a6abbc95196655fd6da2dd9b358.png


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') ;

dabb310cd9c90b747e9719fec716ef16.png


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) ;

0abdef4e332b991e4edc3e9e01bfd9d8.png


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 ;

98fe9a56522232df8ac6001f75fe27a0.png


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') ;

425ba93aff54a79416032c55eaf9fc76.png


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) ;

e4afbbdfd2074b3800a7cd9e42e4c84f.png


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 ;

0328b4ab061c2d33ea0a0aa551ab5bc1.png


在简单比较下时间

3b7b828dfbb85e9159e1f361ac4c75f2.png

0c908c5406f36993139c914e40e80888.png

e84062bab5801014eeac5e20512fd9e2.png

4c81a90b3592414b48e8ad1ec3efddbd.png

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

6d0ea959daafc54e0b9bd42cf3f2acd3.png

f648c5e74f356c525b8e2a70d5045fdb.png

e843190db9fd82d89282f7cf80e1e713.png

4fd135eab920195341838e5f8a4177ad.png

7858687a2ce91f9724f5eaba4c370139.png

7d38822e8b4bb5746a66049a042c7008.png

fdcb6a8ee2f2562bc6eccb6f321cc3e2.png

878233f98977f9121c63fb4c32f26804.png

2f0739b255dfd2d71347dbf1e7e4dbc3.png

并没有什么差别。而且not in和not exists都会使索引失效,但是不影响子查询的索引使用!!!!所以直接说谁比谁快的都是不负责任的说法,还是要具体情况具体分析。分情况使用。那些说not exists比not in快的,这种情况很多,因为不同的原因造成他们的sql的执行计划不同了,所以效率也不同了

抛开执行计划和实际情景,不考虑数据情况,数据量、索引情况甚至统计信息等这些因素,直接说哪一种比较快都是不靠谱的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值