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

CROSS APPLY与OUTER APPLY性能差异问询:全匹配场景下为何前者更快

CROSS APPLY vs OUTER APPLY 性能差异解析

先来看你对比的两段SQL脚本:

UPDATE t SET Amount = applied.MaxAmount 
FROM @test t 
CROSS APPLY ( 
    SELECT MAX(t2.Amount) AS MaxAmount 
    FROM @test t2 
    WHERE t2.Id = t.ForeignId 
) AS applied 

vs

UPDATE t SET Amount = applied.MaxAmount 
FROM @test t 
OUTER APPLY ( 
    SELECT MAX(t2.Amount) AS MaxAmount 
    FROM @test t2 
    WHERE t2.Id = t.ForeignId 
) AS applied

你说得没错——这两段脚本的功能完全一致。因为MAX()作为聚合函数,哪怕子查询里没有匹配到任何行,也会返回一个NULL结果,所以不管用CROSS APPLY还是OUTER APPLY,最终都会更新@test表的每一行,结果没有区别。但大数据集下OUTER APPLY跑得慢很多,核心原因在于两者的执行逻辑和查询优化器的处理方式不同:

  • 过滤与保留逻辑的本质差异
    CROSS APPLY的语义更接近INNER JOIN,而因为你用了MAX(),子查询永远会返回至少一行(要么是实际的最大值,要么是NULL),所以查询优化器能直接推断出:主表的每一行都能匹配到子查询的结果。基于这个推断,优化器会生成更紧凑的执行计划,省去了OUTER APPLY必须做的“检查主表行是否有匹配、无匹配则保留原行”的额外步骤。
    而OUTER APPLY的语义是强制保留主表所有行,哪怕子查询无结果——哪怕你的场景里子查询不可能无结果,优化器还是会按照通用的OUTER APPLY逻辑来处理,这就带来了不必要的行状态维护和匹配检查,大数据集下这些额外操作的开销会被显著放大。

  • 查询优化器的优化优先级
    SQL Server对CROSS APPLY的优化支持更成熟,它可以复用很多针对内连接的优化规则,比如高效的嵌套循环连接、精准的索引查找、对统计信息的充分利用。而OUTER APPLY因为要兼容“无匹配行”的场景,优化器会做更多保守的处理,比如选择开销更高的连接方式(比如哈希连接),或者增加额外的执行步骤来确保主表行不丢失,这自然会拖慢速度。

  • 行数预估的准确性
    对于CROSS APPLY,优化器能准确预估子查询返回行数是1行,从而选择最适合的执行策略;而OUTER APPLY的行数预估会更保守(默认可能考虑子查询返回0行或多行的情况),错误的预估会导致优化器选择低效的执行计划,在大数据量下这种影响尤为明显。

简单来说:虽然功能等效,但CROSS APPLY的语义给了查询优化器更多优化空间,避免了OUTER APPLY的额外逻辑开销,所以在大数据集下性能更优。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:26:18