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

tho*_*ulb 76 sql t-sql database clustered-index sql-server-2008

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

它是"独特的",如果是这样的话怎么样?使它独一无二的最佳方法是什么?

我问,因为我目前正在使用聚集索引来划分逻辑部分中的表,但性能是如此,最近我得到使我的聚簇索引唯一的建议.我想就此发表第二个意见.

谢谢!

Lie*_*ers 79

他们不具有是唯一的,但可以肯定的是鼓励.
我还没有遇到过我想在非唯一列上创建CI的场景.

如果您在非唯一列上创建CI,会发生什么

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

这会导致糟糕的表现吗?

添加唯一符肯定会增加计算和存储它的开销.
如果这种开销将是显着的取决于几个因素.

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


按照Remus在评论中指出的编辑,确实存在创建非唯一CI的用例,这是一个合理的选择.我没有遇到过这些场景只是表明我自己缺乏曝光或能力(选择你的选择).

  • +1因为你说的一切都是正确的,但只是想补充一点:当特定(非唯一)列上的范围扫描是普遍的访问模式时,非唯一CI非常常见. (27认同)
  • @Remus:所以你的意思是你有一个非独特的专栏,比如'Departmentid',你在那里查询类似'DepartmentId BETWEEN 1和100'的内容?*编辑*啊我明白你的意思,是的,日志表中的日期列也是一个很好的例子. (4认同)

mar*_*c_s 25

我想看看索引女王金伯利·特里普在这个话题上说的话:

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

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

* Unique
* Narrow
* Static
Run Code Online (Sandbox Code Playgroud)

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

资料来源: 不断增加的聚类重点辩论 - 再次!

  • 给我介绍索引女王的+1 :-) (10认同)
  • @littlegreen:她说如果你坚持使用GUID(这对于在聚类索引中使用真的很糟糕),那么至少使用`newsequentialid()`来获得几乎顺序化的GUID.但是是的:如果**你**添加你自己的唯一ID(我总是喜欢INT IDENTITY),那么你手头有这个值,你可以使用它(例如建立FK关系).SQL Server添加的唯一文件对您来说是不可见的,因此它们只是您无法使用的开销. (2认同)

Chr*_*isW 8

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

他们没有,而且有时候如果他们不这样做会更好.

考虑一个具有半随机,唯一EmployeeId的表和每个雇员的DepartmentId:如果您的select语句是

SELECT * FROM EmployeeTable WHERE DepartmentId=%DepartmentValue%
Run Code Online (Sandbox Code Playgroud)

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


你有什么参考吗?

聚集索引设计指南例如,它说,

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

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

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

  • 当然,在您的示例中,{DepartmentID,EmployeeID}上的唯一聚簇索引会更好吗?为什么当现有字段以较少的开销(可能是四字节INT)提供唯一性时,系统会创建一个唯一符,并且可以让您在索引中单独运行一些查询? (3认同)