You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle查询执行顺序:LEFT JOIN与WHERE子句的执行先后问题

Oracle中LEFT JOIN与WHERE子句的执行顺序解答

结论

Oracle SQL的逻辑执行顺序是先完成LEFT JOIN关联,再执行WHERE子句过滤。优化器可能会做不改变语义的物理执行优化(比如谓词下推),但不会改变SQL本身的执行逻辑。

测试数据说明

表A

COL_A
-----
1
2
3
4

表B

COL_B
-----
1
2
3
5

执行SQL

select a.col_a, b.col_b
from a  left join b
on a.col_a=b.col_b
where b.col_b <> 5;

完整逻辑计算流程

我们按照SQL的标准语义执行顺序拆解:

  1. 第一步:执行LEFT JOIN关联
    左连接的规则是保留左表(A)的所有行,右表(B)匹配a.col_a = b.col_b条件的行对应填充,匹配不到的位置补NULL,关联后得到的中间结果集为:

    COL_ACOL_B
    11
    22
    33
    4NULL

    注意:B表中col_b=5的行没有匹配的A表行,所以不会出现在左连接的中间结果中。

  2. 第二步:执行WHERE子句过滤
    对中间结果执行b.col_b <> 5的过滤规则:Oracle中NULL和任何值做比较运算的结果都是UNKNOWN,只有判定为TRUE的行才会被保留。因此col_b=NULL的第4行被过滤,最终得到你看到的3行结果:

    COL_ACOL_B
    11
    22
    33

关于优化器等价优化的说明

你可能会发现,如果先过滤B表中col_b=5的行,再和A做左连接,得到的结果和上面完全一致,这是Oracle优化器做的谓词下推等价优化,属于物理执行层面的调整,前提是完全不改变SQL的语义结果,不代表逻辑执行顺序变成了先执行WHERE再执行JOIN。

你可以做个简单验证:把WHERE条件改成WHERE b.col_b IS NULL,执行后会返回COL_A=4、COL_B=NULL的结果。如果逻辑上先过滤B表,B表本身没有col_b=NULL的行,关联后不可能得到这个结果,这就直接验证了逻辑层面一定是先执行LEFT JOIN再执行WHERE。

内容的提问来源于stack exchange,提问作者Rakesh Raikwar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.21 18:36:05