我对表上的索引和视图上的索引(索引视图)之间的区别感到困惑,请澄清一下。
视图上的索引有一些限制,因为视图可以基于各种表和视图的组合。
无论哪种情况,它们都是相似的,随着底层数据的更改,索引可能需要更新或不需要更新。
表上的索引通常总是被使用的 - 通常您至少会有一个唯一索引(主键),并且可能已经确定了其中一个索引要成为聚集索引。
视图上的索引通常只作为优化技术应用,当视图读取变得繁重时,视图上的索引可以通过视图来提高性能。
我使用索引视图来大幅提高查询性能,其中我想按唯一字段组合进行分组,并可能对它们进行一些聚合SUM或计数。
例如,考虑一个包含客户、卡车、距离、日期(以及约30个其他性能列,我现在不想查询)的表。我有数百个客户,他们每个人都有数百辆卡车,每辆卡车每天报告5次距离和其他数据。如果我想查询哪些卡车在哪些月份报告,我创建一个如下的视图:
CREATE VIEW dbo.vw_DistinctUnitMonths
WITH SCHEMABINDING
AS
SELECT CustomerGroup,
CustomerId,
Vehicle,
CAST(DATEADD(MONTH, DATEDIFF(MONTH, 0, Date), 0) AS DATE) AS Month, --Converts Date to First of the Month
SUM(CASE WHEN Miles > 0 THEN Miles ELSE 0 END) AS Miles,
COUNT_BIG(*) AS Count
FROM dbo.PerformanceData
GROUP BY CustomerGroup, CustomerId, Vehicle, CAST(DATEADD(MONTH, DATEDIFF(MONTH, 0, Date), 0) AS DATE)
GO
CREATE UNIQUE CLUSTERED INDEX IX_DistinctUnitMonths ON vw_DistinctUnitMonths (CustomerGroup, CustomerId, Vehicle, Month)
GO
这是一个不使用视图的慢查询:
--Can Be Very Slow!
SELECT CustomerGroup,
CustomerId,
Vehicle,
CAST(DATEADD(MONTH, DATEDIFF(MONTH, 0, Date), 0) AS DATE) AS Month
FROM PerformanceData
WHERE Month >= '2020-01-01'
AND Month < '2020-02-01'
GROUP BY Vehicle, ClientID, ClientGroupId, CAST(DATEADD(MONTH, DATEDIFF(MONTH, 0, Date), 0) AS DATE)
这里有一个运行速度更快的,因为使用了索引视图。
--Much Faster
SELECT CustomerGroup,
CustomerId,
Vehicle,
Month
FROM vw_DistinctUnitMonths WITH (NOEXPAND)
WHERE Month >= '2020-01-01'
AND Month < '2020-04-01'
GROUP BY Vehicle, ClientID, ClientGroupId, Month
由于索引视图仅在客户、组、车辆和月份的唯一组合上创建索引,因此视图的磁盘空间比在源表上对这些列进行索引要小得多。查询视图更快,因为视图中的数据集中在几十兆字节,而不是源表占用的数百吉字节。
另请参阅MSFT Docs:创建索引视图