自适应join是sql server 2019+优化器在批处理模式下自动启用的执行计划特性,仅当右侧输入行数难预估且初始选哈希连接、实际≤100行时,才动态切换为嵌套循环;需列存储索引或显式启用批次模式、兼容级别≥140,并通过执行计划中adaptive="true"及actualjointype确认。

SQL Server 2019 的自适应 JOIN 不是手动“使用”的功能,而是查询优化器在运行时自动启用的执行计划特性——它只在满足特定条件时触发,且无法通过 JOIN 关键字或提示直接开启或关闭。
自适应 JOIN 是什么,以及它何时生效
自适应 JOIN 是 SQL Server 2019 引入的执行计划重写机制,用于缓解“嵌套循环 vs 哈希连接”选择错误带来的性能抖动。它只作用于 INNER JOIN 和 LEFT JOIN,且必须同时满足:
- 查询中存在一个 JOIN 操作,其右侧输入(inner side)大小在编译时难以准确预估(例如含参数化谓词、统计信息陈旧、或来自 TVF/CTE)
- 优化器最初选择了哈希连接(
Hash Join),但实际执行中发现 inner 输入行数极小(通常 ≤ 100 行) - 该 JOIN 被标记为“可切换”,即未被
OPTION (HASH JOIN)或USE HINT('DISABLE_BATCH_MODE')等强制干预
此时,执行引擎会在第一次读取 inner 输入后动态切换为嵌套循环连接(Nested Loops Join),避免构建哈希表的开销。
如何确认你的查询是否启用了自适应 JOIN
打开实际执行计划(不是估算计划),查找带有 Adaptive Join 图标(齿轮+箭头)的运算符节点,并检查其属性中的 Is Adaptive = True 和 Actual Join Type 字段。常见误判点:
-
SELECT * FROM t1 JOIN t2 ON ...执行计划里没看到Adaptive Join?正常——因为 inner 输入行数可准确估计(如主键等值连接 + 统计信息新鲜),优化器不会预留切换路径 - 启用了
QUERYTRACEON 2312或数据库兼容级别 - 使用了
OPTION (RECOMPILE)但 inner 表仍走索引扫描而非查找?可能因谓词未SARGable,导致行数估算偏差大,反而更易触发自适应逻辑
你不能做、但容易误以为能做的三件事
自适应 JOIN 是纯后台行为,不提供用户可控接口:
- 不能用
OPTION (USE HINT('ENABLE_QUERY_OPTIMIZER_HOTFIXES'))启用它——该 hint 影响的是其他修复项,与自适应无关 - 不能对
RIGHT JOIN或FULL OUTER JOIN触发自适应逻辑(SQL Server 当前版本不支持) - 不能通过
DBCC TRACEON(2312, -1)“强制全局开启”——该 trace flag 在 2019+ 已废弃,且自适应本身依赖兼容级别 150+ 和SET STATISTICS XML ON下的实际执行上下文
真正值得你关注的替代控制点
如果你观察到 JOIN 性能不稳定,优先检查这些可操作项,它们比等待自适应更可靠:
- 确保 JOIN 列上有有效统计信息:
UPDATE STATISTICS或开启AUTO_UPDATE_STATISTICS - 避免在 JOIN 条件中对列使用函数:
ON UPPER(t1.name) = UPPER(t2.name)会禁用统计估算,增加自适应触发概率,但代价是失去索引查找能力 - 对高频参数化查询,考虑用
OPTION (RECOMPILE)让每次执行都生成专属计划——这比依赖运行时切换更可预测
自适应 JOIN 是兜底机制,不是调优手段;它解决的是“优化器猜错了怎么办”,而不是“怎么让优化器猜得更准”。真要稳定性能,还是得从统计质量、索引设计和谓词写法入手。










