SQL Server 在执行期间是不是扩展视图的 sql 内联?
Posted
技术标签:
【中文标题】SQL Server 在执行期间是不是扩展视图的 sql 内联?【英文标题】:Does SQL Server expand a view's sql inline during execution?SQL Server 在执行期间是否扩展视图的 sql 内联? 【发布时间】:2016-09-12 21:23:50 【问题描述】:假设我有一个名为 Table1
的(假设的)表,有 500 列,并且有一个名为 View1
的视图,基本上是
select Column1, Column2,..., Column500, ComputedOrForeignKeyColumn1,...
from Table1
inner join ForeignKeyTables .....
现在,当我执行类似
的操作时Select Column32, Column56
from View1
SQL Server 将其变成以下 3 个中的哪一个?
查询 #1:
select Column32, Column56
from
(select
Column1, Column2,..., Column500, ComputedOrForeignKeyColumn1,...
from
Table1
inner join
ForeignKeyTables ......) v
查询 #2:
Select Column32, Column56
from Table1
查询 #3:
select Column32, Column56
from
(select Column32, Column56
from Table1) v
我问这个的原因是我确实有一个非常宽的表和一个位于其顶部的视图(基本上是内部连接以从所有外键 ID 中获取文本),我无法确定 SQL服务器获取所有列,然后选择需要的列或仅获取需要的列(同时也忽略不必要的连接等)...如果是前者,那么视图将不是最好的性能。
【问题讨论】:
很可能是非常接近 #1 的东西 - view 只是一个 stored 语句 - 视图通常是 not旨在提高性能 - 这不是他们的主要目标 - 而是为不同的用户/流程组提供定制的数据“视图” 您应该知道您的“查询 #1”不会获取所有列。查询作为一个整体进行了优化。如果子查询包含外部查询随后忽略的列,则优化器应该能够生成和使用无法返回该列的计划。在 SQL 中,你告诉系统你想要什么,而不是如何去做。 【参考方案1】:SQL Server 查询编译可以分为几个阶段:
-
解析
绑定
优化
在绑定期间执行视图分辨率。在这个阶段,视图引用被其定义替换。此时,将出现未使用的视图列。
下一阶段是优化,将绑定的语法树转换为执行计划。优化器会考虑对执行计划进行多种操作以提高效率,删除未使用的列是最基本的操作之一。此时,未使用的列引用将被删除。
因此,回答您的问题,视图定义中未使用的列不会影响性能,因为优化器会足够聪明地删除它们。
注意:此答案假定视图未编入索引。对于索引视图,解析过程的工作方式不同,并且基表的 UPDATE 存在视图维护开销。
【讨论】:
【参考方案2】:以上都不是。 SQL Server 将解析查询并创建和执行计划。生成的执行计划是根据许多因素计算得出的,例如索引连接等。
检查这样的执行计划,除了你之外的任何人都无法真正回答你的问题。
更多信息请参见How do I obtain a Query Execution Plan?。
【讨论】:
谢谢。我现在分析了查询计划,当通过视图运行查询时(当实际查询或多或少相同时),似乎有更多的键查找。查询直接在表上运行,只有索引扫描和哈希匹配。我猜这需要更多调查,我曾假设它们是等价的。 @Achilles 您在执行计划中看到差异的原因是您删除了 #2 和 #3 中的内部联接,使查询不等效。如果您使用外部联接,则即使您使用视图作为源,也可以从执行计划中删除整个分支/表。至少就您没有从外部连接表中获得任何列而言。但是对于内部连接,必须检查匹配行。【参考方案3】:视图定义在编译的早期阶段与外部查询合并。根据视图的复杂性和 QO 的限制,您可能会或可能不会获得相同的视图执行计划查询与等效查询接触基表。
对于您的特定情况,值得注意的是内部联接不仅从联接表中获取数据,而且还限制了结果(与 IF EXISTS 检查的方式相同)。如果表之间存在声明性 FK,QO 将足够聪明,不会检查引用的表,因为存在由约束保证,否则它必须这样做。
【讨论】:
以上是关于SQL Server 在执行期间是不是扩展视图的 sql 内联?的主要内容,如果未能解决你的问题,请参考以下文章
sql server创建视图添加where条件,条件包含一个参数
带有“选择 x 不为空”的 SQL Server 视图需要很长时间才能完成