16 反连接(anti-join)--优化主题系列
2017-10-11 09:47
225 查看
反连接(anti-join)
反连接其实是特殊的半连接。只是把in/exists换成了notin/not exists
执行计划中,看到有NESTED LOOPS ANTI/HASH JOIN ANTI
就表示有反连接
举个例子(基于HROracle11gR2)下面有2个SQL:
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 in和notexists不能像in和exists那样随意改写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 in和notexists是不是能等价转换。
当然了,一般情况下,notin子查询里面都会排除有NULL的情况,不然查询结果没意义。
现在来过滤掉NULL值。
A LEFT JOIN B 是不是说A有并且B没有
B用NULL代替
那我加个where条件 IS NULL
4000
B.XXX IS NULL 是不是说明A和B
没关联上??
是不是等效于 NOTIN,NOT EXISTS的效果
总结一下in/exists,notin/not exists
一般情况下,当SQL很简单,他们的执行计划是一样的,也就是说他们的性能时一样的。但是SQL一复杂了,他们的执行计划就可能不一样,这个时候就要我们去解决这些问题。这里,我不会给你们讲什么情况下应该用notin什么情况下应该用notexists,因为这些理论是没用的,要具体情况具体分析。后面的章节我会讲解半连接和反连接最底层的原理,把最底层原理搞懂之后,大家以后在遇到in和exists,not
in和notexists就会迎刃而解了。
反连接其实是特殊的半连接。只是把in/exists换成了notin/not exists
执行计划中,看到有NESTED LOOPS ANTI/HASH JOIN ANTI
就表示有反连接
举个例子(基于HROracle11gR2)下面有2个SQL:
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 in和notexists不能像in和exists那样随意改写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 in和notexists是不是能等价转换。
当然了,一般情况下,notin子查询里面都会排除有NULL的情况,不然查询结果没意义。
现在来过滤掉NULL值。
A LEFT JOIN B 是不是说A有并且B没有
B用NULL代替
那我加个where条件 IS NULL
4000
B.XXX IS NULL 是不是说明A和B
没关联上??
是不是等效于 NOTIN,NOT EXISTS的效果
总结一下in/exists,notin/not exists
一般情况下,当SQL很简单,他们的执行计划是一样的,也就是说他们的性能时一样的。但是SQL一复杂了,他们的执行计划就可能不一样,这个时候就要我们去解决这些问题。这里,我不会给你们讲什么情况下应该用notin什么情况下应该用notexists,因为这些理论是没用的,要具体情况具体分析。后面的章节我会讲解半连接和反连接最底层的原理,把最底层原理搞懂之后,大家以后在遇到in和exists,not
in和notexists就会迎刃而解了。
相关文章推荐
- 11 哈希连接(HASH JOIN)--优化主题系列
- 14 外连接(hash join outer)--优化主题系列
- 15 半连接(semi-join)--优化主题系列
- 28 分析函数优化自连接,减少表访问次数 --优化主题系列
- 12 排序合并连接(SORT MERGE JOIN)--优化主题系列
- 29 超大表与超小表HASH JOIN优化方法--优化主题系列
- 使用连接(JOIN)来代替子查询(Sub-Queries) mysql优化系列记录
- MySQL5.7性能优化系列(二)——SQL语句优化(2)——使用 Semi-Join半连接变换优化子查询,派生表和视图
- 使用连接(JOIN)来代替子查询(Sub-Queries) mysql优化系列记录
- 9 join方法--优化主题系列
- 使用连接(JOIN)来代替子查询(Sub-Queries) mysql优化系列记录
- 使用连接(JOIN)来代替子查询(Sub-Queries) mysql优化系列记录
- hibernate系列十五:hql连接查询,查询性能优化,hql批量增删改
- 关于mysql inner join 连接查询的优化
- LINQ系列:LINQ to SQL Join连接
- 【Hive】Hive笔记:Hive调优总结——数据倾斜,join表连接优化
- 【Oracle优化笔记】哈希连接(HASH JOIN)详解
- MYSQL LEFT JOIN连接优化案例一则
- 一次针对Not in的优化--如何让其选择hash join anti
- 27 分页语句优化--优化主题系列