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

如果聚集索引不是唯一的,会发生什么? 可以导致性能不佳,因为插入的行stream到某种“溢出”页面?

它是“独特的”,如果是这样的? 什么是使其独特的最佳方式?

我问,因为我目前正在使用聚集索引来划分我的表的逻辑部分,但性能是如此,最近我得到的build议 ,使我的聚簇索引独特。 我想对此有第二个意见。

谢谢!

他们不必是独一无二的,但肯定会受到鼓励。
我还没有遇到一个场景,但我想在非唯一列上创build一个CI。

如果您在非唯一列上创buildconfiguration项,会发生什么情况

如果聚集索引不是唯一索引,则SQL Server通过添加名为uniqueifier的内部生成的值来使所有重复键唯一

这是否会导致糟糕的performance?

添加一个唯一的确实会增加计算和存储的开销。
如果这个开销会显着取决于几个因素。

  • 表格包含多less数据
  • 插入率是多less?
  • 在一个select中使用CI的频率是多less(当没有覆盖索引时,几乎总是)。

编辑
正如Remus在评论中指出的那样,确实存在使用情况,即创build非唯一的CI将是一个合理的select。 我没有遇到过这种情况,仅仅表明了我自己缺乏暴露性或能力(select你的select)。

我想看看索引的女王金伯利·特里普(Kimberly Tripp)在这个话题上要说些什么:

我将首先介绍关于Clustering Key的build议 – 有几个原因。 首先,这是一个容易做出的决定,其次,尽早作出这一决定有助于积极预防某些types的分裂。 如果您可以防止某些types的基表碎片,那么您可以最小化一些维护活动(其中一些维护活动(在SQL Server 2000中less于SQL Server 2005中的某些维护活动),要求您的表脱机。 好的,我以后会去重build

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

* Unique * Narrow * Static 

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

来源: 不断增长的集群重点辩论 – 再次!

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

他们不这样做,而且有些时候,如果他们不这样做,情况会好一些。

考虑一个包含半随机,唯一EmployeeId和每个员工的DepartmentId的表:如果您的SELECT语句是SELECT * FROM EmployeeTable WHERE DepartmentId =%DepartmentValue%,那么如果DepartmentId是聚集索引,甚至特别是因为)它不是唯一的索引(最好的性能,因为它确保给定DepartmentId中的所有logging都聚集)。


你有什么参考?

例如, “聚集索引devise指南”中提到,

除less数例外情况外,每个表应在列(或列)上定义聚簇索引,这些索引提供以下内容:

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

例如,我对“高度独特性”的理解是,如果大多数查询要select给定城镇内的logging,则select“国家/地区”作为拼凑索引是不好的。