半联结 和 反联结是 oracle 优化器能够选择用来在获取信息时应用的两个密切相关的联结方法(实际上是联结方法的选项)
半联结
IN 的半联结
select /* using in */ department_name
from hr.departments dept
where department_id IN (select department_id from hr.employees emp);
EXISTS 半联结
select /* using exists */ department_name
from hr.departments dept
where EXISTS(select null from hr.employees emp where emp.department_id = dept.department_id);
EXISTS 和 IN 的可替换语法
select /* inner join */ department_name
from hr.departments dept, hr.employees emp
where dept.department_id = emp.department_id;
控制半联结执行计划
半联结 实际上就是双层for循环, 注意下边的: NESTED LOOPS SEMI (半联结的标志)
使用提示控制半联结执行计划
SEMIJOIN - 进行半联结
NO_SEMIJOIN - 不进行半联结
例如:
select /* exists no_semijoin */ department_name
from hr.departments dept
where exists (select /*+ no_semijoin */) null from hr.employees emp where emp.department_id = dept.department_id);
因为我们提供了 no_semijion 的提示, 所以, 执行计划中就没有在使用半联结, 而是使用了 filter(exists (select o from ))
反联结
总结: 实际上, 以上的联结, 我都有在前面的 table join 类型时 有单独拿出来讲过, 所以, 这里不在详细说明.
总结的结果就是, 由于我们使用的优化器一般都是基于成本的, 所以, 只使用 EXISTS 和 外连接 两种.