自适应join在sql server 2019中通过执行时监控右表扫描行数,动态从哈希连接切换为嵌套循环连接;启用需兼容级别150,执行计划中isadaptive="true"且actualjointype与estimatejointype不同即表示已生效。

自适应JOIN在SQL Server 2019里怎么自动选连接算法?
SQL Server 2019的自适应JOIN不是“智能猜”,而是执行时根据实际数据量动态切换物理连接方式。它在查询启动时先用哈希连接(Hash Join)的构建阶段缓存左表(build input)数据,同时持续监控右表(probe input)已扫描的行数;一旦发现右表数据量远小于预期(比如不到阈值的1/10),就立刻中止哈希连接,改用嵌套循环(Nested Loops)完成剩余处理——整个过程对用户透明,不需重写SQL或加提示。
哪些场景下它真能绕过人工调优?
以下情况原本需要手动加 OPTION (HASH JOIN) 或 OPTION (LOOP JOIN) 提示,现在可省:
- 参数化查询中,输入值导致选择性剧烈变化(例如查
WHERE status = @p,@p 有时是高频值“Active”,有时是低频值“Cancelled”) - 统计信息滞后:表刚批量插入百万行但还没
UPDATE STATISTICS,优化器误判右表很小,生成了低效嵌套循环计划;自适应JOIN会在运行时纠正 - 分区表跨分区查询:部分分区数据极少、部分极大,固定连接算法容易在某一分区卡住,自适应机制能逐分区调整
但它不解决什么问题?
自适应JOIN只管“连接算法切换”,不碰底层性能病根:
- 如果JOIN字段没索引,嵌套循环阶段仍会全表扫描右表——
ON t1.id = t2.ref_id中t2.ref_id缺索引,照样慢 - 哈希连接阶段内存不足触发溢出(spill to tempdb),自适应切换也救不了——得调
min memory per query或加资源调控器 - 多层嵌套JOIN(A JOIN B JOIN C JOIN D)只对最外层JOIN启用自适应,内层仍按原计划走
怎么确认它真的起了作用?
查执行计划XML或图形界面里的“Adaptive Join”图标,关键看两个属性:
• IsAdaptive="true" 表示启用了该特性
• ActualJoinType 值可能是 Hash 或 NestedLoops,且与 EstimateJoinType 不同——这才是发生切换的证据
注意:必须开启数据库兼容级别150(SQL Server 2019默认),并确保 SET STATISTICS XML ON 或用 SSMS 查看“包含实际执行计划”;旧版兼容模式或仅看预估计划会看不到真实行为。










