为什么索引视图不允许非唯一聚集索引?

Ami*_*ble 12 sql-server clustered-index materialized-view

我一直在研究使用索引视图来提高一些最常用的视图的性能。

然而,索引视图不支持非唯一聚集索引,这与数据库结构的其余部分设置的优先级略有不同。

例如,这是我们几个表的简化版本。

-Groups-
Group ID    GroupName

-Users-
UserKey    UserName    FullName     GroupID
Run Code Online (Sandbox Code Playgroud)

索引位于 Groups.GroupID(非集群)和 Users.GroupID(集群)上。聚集键位于用户表中的 GroupID 上,因为最常见的是将检索来自特定组的用户范围。显然每个组会有多个用户,所以这个聚集索引是非唯一的。

这让我有点不确定在索引我的视图(例如这个例子)时如何遵循这个优先级,因为我不能有一个非唯一的聚集索引。

ConsumableID    ConsumableVariantID AllowThresholdOverwrite FullPath    GroupID ManufacturerID  Type    ModelID
101              29                 1                       0.1.2.4.    4       3               3       2
Run Code Online (Sandbox Code Playgroud)

实际上,此视图上唯一始终唯一的值是 ConsumableID 列,因此在放置索引的位置方面我几乎没有选择。

当常规表允许时,为什么视图不允许非唯一聚集索引?

Pau*_*ite 22

这篇 Microsoft 技术文章中给出了以下解释:

为什么视图上的第一个索引必须是 CLUSTERED 和 UNIQUE?

它必须是 UNIQUE 以允许在索引视图维护期间通过键值轻松查找视图中的记录,并防止创建具有重复项的视图,这需要特殊的逻辑来维护。它必须是聚集的,因为只有聚集索引才能强制唯一性并同时存储行。

SQL Server 使用增量代数系统来使索引视图与基本数据保持同步。它还为影响一个或多个索引视图的每个 DML 查询自动合并视图维护查询计划运算符。在视图上拥有唯一的聚集索引极大地简化了实现细节。

当前的安排允许将固定形状的维护运算符树形状合并到基本 DML 查询树中,提供正交性,也简化了测试。最终,有朝一日可以增强索引视图以支持非唯一的聚集索引,但是如果时间无限且资源无限(截至撰写本文时,这两种方法均不适用于 SQL Server 开发团队),那么一切皆有可能。

有关显示更新查询计划构建的复杂程度以及细微错误潜入其中的难易程度的示例,请参阅此示例,该示例使用MERGE过滤索引(与索引视图密切相关的功能)发生的错误

  • 如果您尝试更新具有“GROUP BY”子句但并非所有分组表达式都是聚集索引中的键的索引视图,则可能会发生类似的错误。它自 SQL Server 2014 起有效。 (2认同)