SQL Server 视图内联展开适用场景及精确判定规则问询
SQL Server 视图展开(视图内联)判定指南
你提到的视图“展开”操作在SQL Server官方定义中称为视图内联(View Inlining),是查询优化器逻辑优化阶段的默认行为,针对你提到的简单、非嵌套、无索引普通视图,精确判定规则如下:
一、查询优化器必定执行视图展开的场景
只要视图同时满足以下所有条件,一定会触发内联展开,外部查询的谓词会直接下推到基表执行,性能和直接查询基表、使用参数化内联表值函数完全一致:
- 视图定义未包含
TOP、DISTINCT、GROUP BY、HAVING、UNION/UNION ALL、无TOP搭配的ORDER BY、窗口函数、聚合函数、关联非确定性函数的CROSS APPLY/OUTER APPLY等会修改结果集语义的语法 - 视图为普通非索引视图,未添加聚集索引
- 调用视图的查询未使用
NOEXPAND强制提示 - 视图无嵌套其他视图、表值函数
你给出的示例视图完全符合上述条件:
CREATE VIEW vw_Simple AS SELECT Column1 ,Column2 FROM TableA
对应的调用查询会完全展开,WHERE条件直接下推到基表TableA执行:
SELECT Column1 FROM vw_Simple WHERE Column1 BETWEEN @SomeStartDate AND @SomeEndDate
二、查询优化器无法执行视图展开的场景
触发以下任意一种情况时,优化器会放弃展开,先执行视图全量逻辑再处理外部查询的筛选、关联操作:
- 视图定义包含上文提到的会修改结果集语义的特殊语法
- 嵌套视图层级≥2层,或嵌套的子视图本身不符合展开条件
- 视图定义引用了非确定性函数,例如
GETDATE()、NEWID() - 数据库兼容级别低于SQL Server 2008,可能触发历史遗留的谓词下推失效问题
- 视图为索引视图(已创建聚集索引)且未显式指定强制展开的提示
三、灰色场景判定规则
当视图复杂度介于上述两类场景之间时,优化器会基于编译开销评估决定是否展开:如果展开后的逻辑树复杂度超过优化器设置的编译时间阈值,为避免过长的查询编译耗时,优化器会放弃展开。
你可以通过查看实际执行计划验证是否完成展开:如果执行计划中没有单独的视图运算节点,直接显示基表的扫描/查找操作,就代表视图已经被成功展开。也可以执行SET SHOWPLAN_XML ON后运行查询,检查执行计划XML中是否存在ViewReference属性,无该属性则说明展开成功。
内容的提问来源于stack exchange,提问作者Daniel Miradakis
相关产品推荐
相关产品推荐

