您不能使用 CTE 索引视图。即使视图可以有SCHEMABINDING
。这样想吧。为了索引视图,它必须满足两个条件(以及许多其他条件):(a)它已被创建WITH SCHEMABINDING
和(b)它不包含 CTE。为了对视图进行模式绑定,它不需要满足不包含 CTE 的条件。
我不相信存在视图具有 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
在较低版本上使用,不确定):
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)
from都是相同的,因为它仅聚合到. 我猜表中可能有一个也应该是连接标准的一部分,但我不确定。如果是这种情况,我认为这可以折叠为单个索引视图。ClaimSums
pat_id
drug_class
pat_id
drug_class
claims