2

我使用如下代码(简化)创建了一个索引视图(以节省非常耗时的聚合时间):

CREATE VIEW vCosts WITH SCHEMABINDING AS
SELECT   ProjectID
         ,YEAR(Date) AS Year
         ,SUM(Cost) AS YearlyCost
FROM     dbo.DailyAssignments
GROUP BY ProjectID
         ,YEAR(Date)

CREATE UNIQUE CLUSTERED INDEX IX_vCosts ON vCosts (Year, ProjectID)

在此视图上执行 SELECT * 需要一秒钟。但是以下查询需要 30 秒(如果包括更多年份,则更糟):

SELECT *
FROM   vCosts
WHERE  Year = 2001

执行计划表明它实际上使用的是基础表而不是视图(更准确地说,它似乎使用的是 DailyAssignments 表的聚集主键而不是视图的索引)。视图上的 SELECT * 按预期使用索引。

我在其他领域没有同样的问题。以下还使用视图的索引并在不到一秒的时间内完成:

SELECT *
FROM   vCosts
WHERE  ProjectID = 1

谁能帮我理解发生了什么?

4

1 回答 1

4

尝试添加WITH (NOEXPAND)后视图。我也有这个问题。

SELECT *
FROM   vCosts WITH (NOEXPAND)
WHERE  ProjectID = 1

当为视图指定 NOEXPAND 时,查询优化器会考虑使用视图上定义的任何索引。使用可选 INDEX() 子句指定的 NOEXPAND 强制查询优化器使用指定的索引。NOEXPAND 只能为索引视图指定,不能为未索引视图指定。

来源这里http://technet.microsoft.com/en-us/library/ms181151(v=sql.105).aspx

于 2014-05-28T14:38:02.607 回答