SQL Server 2022中视图本身不决定是否启用自适应连接,其执行计划是否含<Adaptive>1</Adaptive>节点取决于外层查询是否满足批处理模式条件:需兼容级别≥150、存在列存储索引或启用批次模式运算符,且非行模式执行。

SQL Server 2022 中的视图本身不“支持”或“不支持”自适应连接——它完全取决于视图被引用时的**实际执行计划生成上下文**。视图只是存储的 SELECT 语句,是否启用批处理模式自适应联接(Adaptive Joins),由查询编译器在调用该视图的外部查询中决定,且需同时满足多个硬性条件。
视图里写JOIN,为什么执行计划没出现Adaptive节点?
常见现象是:你在 SSMS 里直接 SELECT * FROM dbo.MyView,看执行计划 XML 却找不到 <Adaptive>1</Adaptive>。原因很实在:
- 视图定义本身不触发编译;真正编译的是外层查询,而外层若未启用批处理模式(如运行在行模式下、缺少列存储索引或兼容级别 Adaptive Join 根本不会被考虑
- 视图若含
ORDER BY、TOP、FOR XML等终止运算符,会强制使用行模式执行,排除批处理模式路径 - 即使外层查询走批处理模式,若视图内 JOIN 的任意一侧没有列存储索引(或非聚集列存储索引 + 合适的 WHERE 过滤),优化器也不会选
Adaptive Join—— 它只在批处理模式下可用 -
Adaptive Join要求至少一个输入能快速扫描(通常是列存储表),如果视图里全是行存储堆/聚集索引,即便兼容级别是 160,也只会看到普通Hash Join或Nested Loops
怎么让调用视图的查询实际用上Adaptive Join?
关键不在视图定义里加什么,而在**调用方式 + 基础设施准备**:
- 确保数据库兼容级别 ≥ 150(SQL Server 2019 起):
ALTER DATABASE [YourDB] SET COMPATIBILITY_LEVEL = 160; - 视图中参与 JOIN 的大表,至少有一侧必须有列存储索引(哪怕是非聚集的);小表可以是行存储,但要有统计信息且已更新:
UPDATE STATISTICS dbo.FactSales WITH FULLSCAN; - 外层查询不能带抑制批处理的提示,例如
OPTION (QUERYTRACEON 9451)或显式LOOP JOIN;也不要加OPTION (USE HINT('DISABLE_BATCH_MODE_ADAPTIVE_JOINS')) - 如果视图被嵌套在存储过程中,确认该过程未用
WITH RECOMPILE频繁干扰计划缓存,否则自适应决策可能每次重做、效果不稳定
视图定义里能做的唯一“配合”动作
不是开启自适应,而是**避免意外禁用它**:
- 别在视图定义里写
INNER JOIN ... ON ... OPTION (HASH JOIN)—— 查询提示会固化连接类型,覆盖自适应逻辑 - 避免在视图中用
SELECT *引用宽表(尤其含大量 LOB 列),这可能导致内存预估失准,间接触发ERROR 701,让优化器回退到保守策略 - 如果视图常被用于报表类场景(大结果集 + 多聚合),可考虑在调用处显式加
OPTION (USE HINT('ENABLE_QUERY_OPTIMIZER_HOTFIXES')),某些补丁会影响自适应阈值计算
真正起作用的从来不是视图本身,而是你如何用它、底表长什么样、以及外层查询有没有给优化器留出判断空间。最常被忽略的一点:哪怕所有条件都满足,Adaptive Join 也只对第一个输入扫描完后才做切换决策——如果你的视图被 WHERE 条件提前过滤掉 99% 数据,它很可能连“自适应”的机会都没有,直接走 Nested Loops 就结束了。

















