如果聚集索引不是唯一的,会发生什么?是否会导致性能不佳,因为插入的行会流向某些类型的“溢出”页面?
它是“独特的”,如果是这样的话怎么样?使它独特的最佳方法是什么?
我在问,因为我目前正在使用聚集索引在逻辑部分划分我的表,但性能一般,最近我得到the advice以使我的聚簇索引唯一。我想就此发表第二个意见。
谢谢!
答案 0 :(得分:76)
他们 不具有独特性,但肯定会受到鼓励 我还没有遇到过我想在非唯一列上创建CI的场景。
如果您create a CI on a non-unique column
,会发生什么如果聚集索引不是唯一的 索引,SQL Server使任何重复 通过内部添加唯一键 生成的值称为唯一化
这会导致糟糕的表现吗?
添加 uniqueifier 肯定会增加计算和存储它的开销 如果这种开销明显取决于几个因素。
修改强>
正如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索引会增加成本重建(由于现在更有可能选择群集密钥)。
答案 2 :(得分:8)
群集索引必须是唯一的吗?
他们不这样做,有时候如果他们不这样做会更好。
考虑一个带有半随机,唯一EmployeeId的表,以及每个员工的DepartmentId:如果你的select语句是
SELECT * FROM EmployeeTable WHERE DepartmentId=%DepartmentValue%
然后,如果DepartmentId
是聚集索引,那么性能最佳,即使(或者甚至特别是因为)它不是唯一索引(最适合性能,因为它确保给定DepartmentId中的所有记录都是聚类的)
你有参考吗?
有Clustered Index Design Guidelines例如,
除了少数例外,每张桌子 应该定义一个聚簇索引 在提供的列或列上 以下内容:
- 可用于常用查询。
- 提供高度独特性。
- 可用于范围查询。
例如,我对“高度独特性”的理解是,如果您的大多数查询想要选择给定城镇内的记录,选择“国家”作为克制索引是不好的。