sql server 分区上的非聚集唯一索引

bmk*_*bmk 7 sql-server-2008 partitioning

SQL Server 2008需要在分区上创建唯一的非聚集索引,以在索引定义中包含分区字段。

我想知道为什么。

Rem*_*anu 7

简短的回答:

如果集群键不是键集的一部分,则无法保证所有分区的索引唯一性。

长长的故事:

保证唯一性的唯一方法是通过 B 树结构强制执行唯一性。使用 B 树真的很容易强制唯一性,因为任何键在 B 树中都有一个确定的逻辑位置(在它的左邻居,即较小的键和右邻居,即较大的键之间)。由于每个键值都可以插入树中的单个位置,因此很容易保证唯一性:只需在插入期间检查该位置是否已被现有行占用。

跨所有分区的分区唯一性更棘手,因为涉及许多B 树结构(每个分区一个)。每个都可以保证分区内的唯一性,但它们一起不能保证所有分区的全局唯一性:分区 X 中的键也可能出现在分区 Y 中。因此,为了保留“唯一索引”的语义,聚簇列必须成为关键的一部分。这样每个键值确定性地绑定到特定分区:键不能出现在分区 X 和 Y 中,因为分区列是键的一部分,因此键可以完全属于分区 XY。

@MarkStoreySmith 问:那么为什么 SQL Server 不通过导航每个 B 树结构、获取不存在被测试值的范围锁并保持直到遍历每个 B 树来检查唯一性?寻找每个 B 树将是一个性能猪(想想在每次插入时要检查 15,000 个分区)。而且锁定的复杂性(从一个 B 树跳到下一个 B 树)也很严重,可能会导致死锁。


Wri*_*ree 0

这可能只是因为索引需要与分区对齐,因为索引本身需要分区(即存储在驱动器上的不同位置)。如果索引不对齐就会出现跨分区指针。