ITPub博客

首页 > 数据库 > Oracle > 外连接嵌套循环为何无法更改驱动表

外连接嵌套循环为何无法更改驱动表

原创 Oracle 作者:a960549548 时间:2025-08-04 09:58:09 0 删除 编辑

        相信各位大佬在做SQL优化的时候,发现一条走外连接的SQL语句表连接方式是嵌套循环,并发现有时将从表作为驱动表执行效率可能会更高,于是兴致勃勃地使用leading(xx)的hint,发现驱动表并无变化。那么这是为什么呢,今天就展开讲讲。

         要理解 外连接中嵌套循环连接无法随意更改驱动表 的问题,需要从 外连接的语义约束 和 嵌套循环的工作机制 两个核心角度分析:

  1. 外连接的语义外连接的核心是 保留某一侧表的全部行(即使另一侧无匹配):

    • 左外连接( LEFT JOIN):保留 左表的所有行,右表无匹配时用 NULL填充;
    • 右外连接( RIGHT JOIN):保留 右表的所有行,左表无匹配时用 NULL填充;
    • 全外连接( FULL JOIN):保留 左右表的所有行,无匹配时各自用 NULL填充(但全外连接很少用嵌套循环,这里不展开)。
  2. 嵌套循环连接(NLJ)的工作机制NLJ是 外层循环驱动内层循环的连接方式:

    • 驱动表(外层):先扫描驱动表的每一行;
    • 被驱动表(内层):用驱动表的行去查询内层表(通常通过索引),返回匹配结果。 驱动表的选择直接决定了 哪些行能进入结果集(只有驱动表的行才会被外层循环处理)。

        外连接的 保留逻辑 要求: 必须处理被保留表的所有行 。而嵌套循环的 驱动表 决定了 外层循环的行 ——只有用 被保留的表作为驱动表 ,才能保证其所有行都被处理,否则会 违反外连接的语义 。

        下面来举个例子。

explain plan for select /*+ use_nl(d,e) leading(e) */  * from dept d left join emp e on d.deptno = e.deptno;
select * from table(dbms_xplan.display);


        leading(e)表示让EMP表作为驱动表。

        从执行计划中我们可以看到,DEPT与EMP是采用嵌套循环进行连接的,这说明use_nl(d,e)生效了。执行计划中驱动表为DEPT,虽然设置了leading(e),但是没有生效。

        为什么leading(e)没有生效呢? 因为DEPT与EMP是外连接,DEPT是主表,EMP是从表,外连接走嵌套循环的时候驱动表只能是主表。

为什么两表关联是外连接的时候,走嵌套循环无法更改驱动表呢?

        

情况1:正确选择驱动表(左表 DEPT作为驱动表)

嵌套循环的工作流程:

  • 外层循环:扫描 DEPT表的 所有4行(左表被保留,必须全部处理);
  • 内层循环:对每个部门的 deptno,查询 emp表;
  • 结果:保留左表的4行,无员工的部门用 NULL填充(符合左外连接语义)。
情况2:错误选择驱动表(右表 order作为驱动表)

如果强制用右表作为驱动表,嵌套循环的流程变为:

  • 外层循环:扫描 emp表的 4行(右表未被保留,无需全部处理);
  • 内层循环:对每个员工的 deptno,查询 DEPT表;
  • 结果: 只返回有员工的部门, 无员工的部门会丢失,完全违反了左外连接“保留左表所有行”的语义。

         可以简单理解为 因为嵌套循环需要传值,主表传值给从表之后,如果发现从表没有关联上,直接显示为 NULL 即可;但是如果是从表传值给主表,没关联上的数据不能传值给主表,不可能传 NULL 给主表,所以两表关联是外连接的时候,走嵌套循环驱动表只能固定为主表。

        

需要注意的是, 如果外连接中 从表 有过滤条件,那么此时外连接会变为内连接, 例如下面 SQL 。

select /*+ leading(e) use_nl(d,e)*/ * from dept d left join emp e on d.deptno = e.deptno where e.sal < 3000;


        HINT 指定了让从表 EMP 作为嵌套循环驱动表,从执行计划中我们看到, EMP 确实是作为嵌套循环的驱动表,而且执行计划中没有 OUTER 关键字,这说明 SQL 已经变为内连接。

        为什么外连接的从表有过滤条件会变成内连接呢?

        因为 外连接的从表有过滤条件已经排除了从表与主表没有关联上显示为 NULL 的情况。


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70013625/viewspace-3092681/ ,如需转载,请注明出处,否则将追究法律责任。

下一篇: Dg broker如何配置
请登录后发表评论 登录
全部评论
Oracle ACE,MySQL 8.0 OCP,PMP,拥有OceanBase OBCP,TiDB PCTP,GoldenDB GDCP等多项认证,ITPUB认证专家,微信公众号:DBA之友。

注册时间:2022-02-08

  • 博文量
    132
  • 访问量
    171511