聚集索引必须是唯一的吗?

时间:2010-12-02 08:17:01

标签: sql database tsql sql-server-2008 clustered-index

如果聚集索引不是唯一的,会发生什么?是否会导致性能不佳,因为插入的行会流向某些类型的“溢出”页面?

它是“独特的”,如果是这样的话怎么样?使它独特的最佳方法是什么?

我在问,因为我目前正在使用聚集索引在逻辑部分划分我的表,但性能一般,最近我得到the advice以使我的聚簇索引唯一。我想就此发表第二个意见。

谢谢!

3 个答案:

答案 0 :(得分:76)

他们 不具有独特性,但肯定会受到鼓励 我还没有遇到过我想在非唯一列上创建CI的场景。

如果您create a CI on a non-unique column

,会发生什么
  

如果聚集索引不是唯一的   索引,SQL Server使任何重复   通过内部添加唯一键   生成的值称为唯一化

这会导致糟糕的表现吗?

添加 uniqueifier 肯定会增加计算和存储它的开销 如果这种开销明显取决于几个因素。

  • 该表包含多少数据。
  • 插入率是多少。
  • 在选择中使用CI的频率(当没有覆盖索引时,几乎总是如此)。

修改
正如Remus在评论中指出的那样,确实存在创建非唯一CI的用例是合理的选择。我没有遇到过这些情景只是表明我自己缺乏曝光或能力(选择你的选择)。

答案 1 :(得分:25)

我想查看索引女王金伯利·特里普(Kimberly Tripp)对此话题的看法:

我将从我对群集密钥的建议开始 - 出于几个原因。首先,这是一个简单的决策,其次,早期做出这个决定有助于主动防止某些类型的碎片。如果您可以阻止某些类型的基表碎片,那么您可以最小化一些维护活动(其中一些在SQL Server 2000中,而在SQL Server 2005中较少,需要您的表脱机)。好的,我稍后会去重建......

让我们从我在群集密钥中寻找的关键事项开始:

* Unique
* Narrow
* Static

为什么选择独特? 集群密钥应该是唯一的,因为集群密钥(如果存在)用作来自所有非集群索引的查找密钥。以图书背面的索引为例 - 如果您需要查找索引条目指向的数据 - 该条目(索引条目)必须是唯一的,否则哪个索引条目将是您要查找的条目?因此,在创建聚簇索引时 - 它必须是唯一的。但是,SQL Server不要求在唯一列上创建群集密钥。您可以在任何您想要的列上创建它。在内部,如果群集密钥不是唯一的,那么SQL Server将通过向数据添加4字节整数来“取消它”。因此,如果聚簇索引是在非独特的东西上创建的,那么不仅在创建索引时会产生额外的开销,还会浪费磁盘空间,INSERT和UPDATE上的额外成本,而在SQL Server 2000中,clustereD索引会增加成本重建(由于现在更有可能选择群集密钥)。

来源: Ever-increasing clustering key debate - again!

答案 2 :(得分:8)

  

群集索引必须是唯一的吗?

他们不这样做,有时候如果他们不这样做会更好。

考虑一个带有半随机,唯一EmployeeId的表,以及每个员工的DepartmentId:如果你的select语句是

SELECT * FROM EmployeeTable WHERE DepartmentId=%DepartmentValue%

然后,如果DepartmentId是聚集索引,那么性能最佳,即使(或者甚至特别是因为)它不是唯一索引(最适合性能,因为它确保给定DepartmentId中的所有记录都是聚类的)


  

你有参考吗?

Clustered Index Design Guidelines例如,

  

除了少数例外,每张桌子   应该定义一个聚簇索引   在提供的列或列上   以下内容:

     
      
  • 可用于常用查询。
  •   
  • 提供高度独特性。
  •   
  • 可用于范围查询。
  •   

例如,我对“高度独特性”的理解是,如果您的大多数查询想要选择给定城镇内的记录,选择“国家”作为克制索引是不好的。