繁体   English   中英

SQL Server如何处理视图后面的表上的索引?

[英]How does SQL Server treat indexes on a table behind a view?

所以我试图了解SQL Server如何在视图后面的表上使用索引。 下面是场景:表A在字段1和2上具有复合聚簇索引,在字段3和4上具有非聚簇索引。

视图A针对表A编写以过滤掉其他字段,但字段1-4是视图的一部分。 因此,我们编写一个查询,将视图连接到非聚簇索引字段上的另一个表。

生成的查询计划使用聚簇索引扫描(而不是预期的非聚簇索引搜索)命中表A. 但是,如果我们用表替换FROM子句中的视图,则查询计划会访问非聚簇索引,并获得我们预期的索引搜索。

SQL引擎是否应该使用构建视图的表上的索引? 既然没有,为什么不呢?

当您考虑非物化视图和优化时 - 想象它们是这样的:

引擎将视图文本“剪切并粘贴”到您执行的每个查询中。

好吧,这不是100%真实,但它可能是最有用的方式来考虑性能方面的预期。

但是,观点可能很棘手。 人们倾向于认为仅仅因为列在视图中,这意味着在查询性能方面有重要意义。 事实是,如果使用您的视图的查询不包含一组列,则可以“优化掉”。 因此,如果您要在视图中从基表中选择每一列,然后在实际使用视图时只选择一列或两列,则只考虑您选择的那两列,将优化查询。

这样做的另一个后果是您可以使用视图来非常积极地平整表结构。 所以,比方说,我有以下架构:

Widget
-------
ID (UNIQUE)
Name
Price
WidgetTypeID (FK to WidgetType.ID)

WidgetType
----------
ID (UNIQUE)
Name

vw_Widgets
----------
SELECT w.ID, w.Name, w.Price, w.WidgetTypeID, wt.Name AS TypeName
FROM Widgets w
LEFT JOIN WidgetType wt
   ON wt.ID = w.WidgetTypeID;

请注意视图定义中的LEFT JOIN。 如果您只是简单地SELECT Name, Price FROM vw_Widgets ,您会注意到WidgetType甚至没有参与查询计划! 它完全被优化了! 这适用于跨唯一列的LEFT JOINS,因为优化器知道由于WidgetType的ID是UNIQUE,因此它不会从连接生成任何重复的行。 由于存在FK,您知道可以将连接保留为LEFT连接,因为您将始终拥有相应的行。

因此,带有观点的故事的寓意是,您在一天结束时选择的列是重要的列,而不是视图中的列。 视图在创建时不会进行优化 - 它们在使用时会进行优化。

你的问题不是关于观点

你的问题实际上更通用 - 为什么你不能使用NC索引? 我无法告诉你真的因为我看不到你的架构或你的具体查询,但足以说明在某个时刻,优化器会发现查找其他字段的成本超过了它的成本。扫描表(因为搜索是昂贵的)并忽略您的非聚集索引。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM