因此,我刚刚发现SQL Server 2008不允许您在定义中使用CTE索引视图,但允许您alter在查询中添加with schemabinding视图定义。是否有充分的理由呢?由于我不知道的某些原因,这有意义吗?我的印象是,WITH SCHEMABINDING主要目的是允许您为视图编制索引
alter
with schemabinding
WITH SCHEMABINDING
新功能和改进功能以及更多的查询操作
;with x as ( select rx.pat_id ,rx.drug_class ,count(*) as counts from rx group by rx.pat_id,rx.drug_class ) select x.pat_id ,x.drug_class ,x.counts ,SUM(c.std_cost) as [Healthcare Costs] from x inner join claims as c on claims.pat_id=x.pat_id group by x.pat_id,x.drug_class,x.counts
和创建索引的代码
create unique clustered index [TestIndexName] on [dbo].[MyView] ( pat_id asc, drug_class asc, counts asc)
您无法使用CTE索引视图。尽管视图 可以 有SCHEMABINDING。这样想吧。为了索引视图,它必须满足两个条件(以及许多其他条件):(a)已经创建,WITH SCHEMABINDING并且(b)不包含CTE。为了schemabind视图,它并 没有 需要满足,它不包含CTE的条件。
SCHEMABINDING
我不认为在这种情况下视图具有CTE 并 会从索引中受益。这是您实际问题的外围,但是我的直觉是您正在尝试对该视图编制索引以神奇地使其更快。索引视图不一定比对基表的查询要快-有某种原因的限制,只有在特定的用例才有意义。请注意,不要盲目地将所有视图编入索引,这是一个神奇的“快点”按钮。还请记住,索引视图需要维护。因此,这将增加工作负载中影响基本表的所有DML操作的成本。
SCHEMABINDING是 不是 只是用于索引视图。它也可以用于UDF之类的功能,以帮助说服确定性,也可以用于视图和函数,以防止对基础架构进行更改,并且在某些情况下可以提高性能(例如,当UDF不受架构约束时,优化器可能必须创建一个表假脱机来处理任何潜在的DDL更改)。因此,请不要认为可以对视图进行架构绑定但不能为它建立索引是很奇怪的。为视图建立索引需要它,但是关系不是相互的。
对于您的特定情况,我建议这样做:
CREATE VIEW dbo.PatClassCounts WITH SCHEMABINDING AS SELECT pat_id, drug_class, COUNT_BIG(*) AS counts FROM dbo.rx GROUP BY pat_id, drug_class; GO CREATE UNIQUE CLUSTERED INDEX ON dbo.PatClassCounts(pat_id, drug_class); GO CREATE VIEW dbo.ClaimSums WITH SCHEMABINDING AS SELECT pat_id, SUM(c.std_cost) AS [Healthcare Costs], COUNT_BIG(*) AS counts FROM dbo.claims GROUP BY pat_id; GO CREATE UNIQUE CLUSTERED INDEX ON dbo.ClaimSums(pat_id); GO
现在,您可以创建一个仅在这两个索引视图之间进行联接的非索引视图,并且它将利用索引(您可能必须NOEXPAND在较低版本上使用,不确定):
NOEXPAND
CREATE VIEW dbo.OriginalViewName WITH SCHEMABINDING AS SELECT p.pat_id, p.drug_class, p.counts, c.[Healthcare Costs] FROM dbo.PatClassCounts AS p INNER JOIN dbo.ClaimSums AS c ON p.pat_id = c.pat_id; GO
现在,所有这些都假定值得对这些信息进行预汇总-如果您不经常运行此查询,但是对数据进行了很多修改,则最好不要创建索引视图。
另外请注意,每个+组合的SUM(std_cost)fromClaimSums视图都将相同,因为它仅汇总到。我猜有可能是在那个应该是连接标准太部分表,但我不知道。如果是这样,我认为可以将其折叠为一个索引视图。pat_id``drug_class``pat_id``drug_class``claims
SUM(std_cost)
ClaimSums
pat_id``drug_class``pat_id``drug_class``claims