16 反连接(anti-join)--优化主题系列

反连接(anti-join)

 

反连接其实是特殊的半连接。只是把in/exists换成了notin/not exists

执行计划中,看到有NESTED LOOPS ANTI/HASH JOIN ANTI 就表示有反连接

 

举个例子(基于HROracle11gR2)下面有2SQL

select department_name

 from hr.departments dept

 where department_id NOT IN

 (select department_id from hr.employees emp);

 

select department_name

 from hr.departments dept

 where NOT EXISTS (select null from hr.employees emp

 where emp.department_id = dept.department_id);

 

以上两个SQL不等价


NOT IN执行计划是filter对吧??


NOT EXISTS就是正常的JOIN方式了吧

 

令人惊讶的是,not in不返回结果,notexists返回16行。

这里也说明not innotexists不能像inexists那样随意改写SQL

为什么用not in不返回结果呢??因为子查询

select department_id from hr.employees emp

会返回NULL值。Oracle有个缺陷:

in里面有NULL会返回结果,比如下面SQL

select department_name from hr.departments dept wheredepartment_id in(10,50,null);

not in 里面有NULL就不会返回结果,直接返回NULL

select department_name from hr.departments dept wheredepartment_id not in(10,50,null);

 

我们在做SQL优化的时候,一定要注意not innotexists是不是能等价转换。

当然了,一般情况下,notin子查询里面都会排除有NULL的情况,不然查询结果没意义。

现在来过滤掉NULL值。


A LEFT JOIN B 是不是说A并且B没有 BNULL代替

那我加个where条件 IS NULL

B.XXX IS NULL 是不是说明AB 没关联上??

是不是等效于 NOTIN,NOT EXISTS的效果

 

总结一下in/existsnotin/not exists 一般情况下,当SQL很简单,他们的执行计划是一样的,也就是说他们的性能时一样的。但是SQL一复杂了,他们的执行计划就可能不一样,这个时候就要我们去解决这些问题。这里,我不会给你们讲什么情况下应该用notin什么情况下应该用notexists,因为这些理论是没用的,要具体情况具体分析。后面的章节我会讲解半连接和反连接最底层的原理,把最底层原理搞懂之后,大家以后在遇到inexistsnot innotexists就会迎刃而解了。


  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值