【问题标题】:WHERE Clause Performance While Querying an Indexed View查询索引视图时的 WHERE 子句性能
【发布时间】:2014-07-17 20:31:12
【问题描述】:

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

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

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

【问题讨论】:

    标签: sql sql-server sql-server-2008-r2 indexed-view


    【解决方案1】:

    尝试在查看后添加WITH (NOEXPAND)。我也有这个问题。

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

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

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

    【讨论】:

    • 成功了,谢谢!但为什么这是必要的?您能否将我引向我可以阅读的来源,以了解为什么优化器会选择在我的案例中扩展视图(使用 YEAR(date))?
    猜你喜欢
    • 1970-01-01
    • 2014-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-14
    • 2012-12-29
    • 1970-01-01
    • 2020-06-03
    相关资源
    最近更新 更多