Mik*_*Fal 9 sql sql-server indexing sql-server-2005
所以我试图了解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;
Run Code Online (Sandbox Code Playgroud)
请注意视图定义中的LEFT JOIN.如果您只是简单SELECT Name, Price FROM vw_Widgets,您会注意到WidgetType甚至没有参与查询计划!它完全被优化了!这适用于跨唯一列的LEFT JOINS,因为优化器知道由于WidgetType的ID是UNIQUE,因此它不会从连接生成任何重复的行.由于存在FK,您知道可以将连接保留为LEFT连接,因为您将始终拥有相应的行.
因此,带有视图的故事的寓意是,您在一天结束时选择的列是重要的列,而不是视图中的列.视图在创建时不会进行优化 - 它们在使用时会进行优化.
你的问题不是关于观点
你的问题实际上更通用 - 为什么你不能使用NC索引?我无法告诉你真的因为我看不到你的架构或你的具体查询,但足以说明在某个时刻,优化器会发现查找其他字段的成本超过了它的成本.扫描表(因为搜索是昂贵的)并忽略您的非聚集索引.