一个表索引和一个视图索引有什么区别?

6

我对表上的索引和视图上的索引(索引视图)之间的区别感到困惑,请澄清一下。

3个回答

4
实际上没有区别。表或视图上的索引基本上用于加快搜索速度。
主要是:视图通常没有索引。当您向视图添加聚集索引时,您实际上正在将该视图“实体化”为系统维护的、始终自动更新的“伪表”,该伪表存在于磁盘上,像表一样使用磁盘空间,并且由于它已经几乎是一个表,因此您还可以向索引视图添加其他索引。
因此,实际上在表和索引视图之间几乎没有区别,在表和索引视图上的索引之间几乎没有任何区别。

0

视图上的索引有一些限制,因为视图可以基于各种表和视图的组合。

无论哪种情况,它们都是相似的,随着底层数据的更改,索引可能需要更新或不需要更新。

表上的索引通常总是被使用的 - 通常您至少会有一个唯一索引(主键),并且可能已经确定了其中一个索引要成为聚集索引。

视图上的索引通常只作为优化技术应用,当视图读取变得繁重时,视图上的索引可以通过视图来提高性能。


0

我使用索引视图来大幅提高查询性能,其中我想按唯一字段组合进行分组,并可能对它们进行一些聚合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:创建索引视图


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接