查询索引视图时的 WHERE 子句性能
Posted
技术标签:
【中文标题】查询索引视图时的 WHERE 子句性能【英文标题】:WHERE Clause Performance While Querying an Indexed View 【发布时间】: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
谁能帮我理解发生了什么?
【问题讨论】:
【参考方案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))?以上是关于查询索引视图时的 WHERE 子句性能的主要内容,如果未能解决你的问题,请参考以下文章