SQL Server执行计划中JOIN与ON的区别及逻辑处理顺序疑问
要理清这个问题,首先要区分SQL逻辑处理顺序(绑定顺序)和数据库实际生成的物理执行计划的差异:
1. 逻辑绑定阶段:ON排在JOIN之前的设计原因
官方给出的顺序是语法绑定校验阶段的执行逻辑,和实际数据读取的执行顺序没有直接关系,这个阶段核心做合法性校验,不涉及真实数据操作:
- 第一步
FROM:先校验查询涉及的表是否存在、当前用户是否有对应访问权限,加载相关表的元数据 - 第二步
ON:校验关联条件的合法性,比如关联字段是否在对应表中存在、字段类型是否允许比较,你给出的第二个示例ON person.badcolumn = country.code就是在这个阶段直接报错,根本不会进入后续执行计划生成环节 - 第三步
JOIN:确认关联类型(内连接、左连接、右连接等)合法,将关联后的结果集作为逻辑临时集合,供给后续WHERE、GROUP BY等子句调用
你推测的「先校验ON合法性判断关联是否可执行」是完全正确的,这个顺序设计就是为了提前拦截不合法的关联条件,避免后续做无用的绑定操作。
2. 物理执行阶段(以Nested Loop Join为例)的功能差异
到了实际执行环节,JOIN和ON的功能完全独立:
JOIN对应关联算法的执行框架:Nested Loop Join的逻辑是先选定一张表作为外层驱动表,逐行遍历驱动表的每一条记录,再到内层被驱动表查找匹配记录ON对应关联匹配的判断规则:遍历到的外层表记录和内层表记录是否满足ON后的条件,只有满足条件的记录才会作为关联成功的结果返回
你给出的第一个示例ON 1=0就非常典型:执行阶段引擎识别到ON条件永远为假,直接跳过Nested Loop的实际遍历流程,直接返回空结果集,不需要扫描任何表的数据,这就是ON规则优先于JOIN执行的体现。
补充说明
逻辑绑定顺序和物理执行顺序不需要完全对齐,比如引擎做了谓词下推优化的情况下,ON的过滤条件可能会提前下推到单表扫描阶段先过滤数据,减少后续JOIN要处理的数据量,但逻辑绑定阶段的顺序还是固定的ON在前、JOIN在后,因为合法性校验必须在关联逻辑绑定之前完成。
内容的提问来源于stack exchange,提问作者David542
相关产品推荐
相关产品推荐

