复合聚集索引 vs 非唯一聚集索引,在这种情况下哪一个更好/更差?

4
我有一个数据库,其中所有表都包含一个名为 Site 的列( char(4))和一个名为 PrimaryId 的列( int )。

当前,所有表上的聚集索引都是这两个列的组合。许多客户只有一个站点,因此在这些情况下,将聚集索引更改为仅包括 PrimaryId 肯定是有意义的。

但是,在存在多个站点的情况下,我想知道仅使用 PrimaryId 作为聚集索引是否仍然有利?拥有较小的聚集索引可能会产生比具有唯一聚集索引更好的性能吗?

如果相关的话,通常不会有超过几个站点。10个站点已经很多了。


1
你需要根据自己的数据集和查询模式进行测量,才能确切地知道。并没有一种通用的答案。 - Damien_The_Unbeliever
感谢@Damien_The_Unbeliever。使用我目前正在使用的数据库,速度确实更快。只是试图在自己进行测试和从他人那里获得输入之间取得平衡。如果有人能提供一些指导,就不想浪费太多时间 :) - BVernon
在where子句中,site字段或primaryid哪一列使用最频繁? 我认为在where条件中使用最频繁的应该是聚集索引。 - KumarHarsh
@KumarHarsh PrimaryId是一个主键,但通常它们会一起使用。毫无疑问,PrimaryId绝对需要在CI中。我发现非唯一索引的UNIQUIFIER sql添加了4个字节。既然这与Site字段的大小相同,我倾向于此时使用复合CI。 - BVernon
2个回答

6

答案很简单,唯一索引始终比非唯一索引更好。 这背后有一些数学原理,但是唯一性越大,服务器查找索引中的记录的速度就越快。

聚集索引非常好,因为它们在磁盘上物理排序记录,并且在唯一键上使用聚集索引总是一个好主意。

使用主键的聚集索引在处理大数据时会有很好的性能表现。 如果您的列中的数据不高,则不会有太大影响。


是的,我刚好注意到当我将查询仅切换到PrimaryId时,一些查询运行得更快。但我的测试数据库并不一定是每个人都在使用的好样本,所以...这就是为什么我在问了。感谢您的回答。 - BVernon
2
实际上,在SQL Server中,聚集索引必须是唯一的(因为这是每个表中的行定位方式 - 所以它必须单独找到每一行)。 如果您没有自己使其唯一,则SQL Server将添加一个4字节的唯一标识符“隐藏”列以使其唯一。 - marc_s

2
我最近读了一篇关于非聚集索引如何匹配表行的文章。我将尝试总结我认为与您的问题相关的内容。
在索引的上下文中,有两种类型的表:
堆 - 没有聚集索引的表
聚集索引 - 有聚集索引的表
在第一种情况下,非聚集索引使用基于 RIP 的书签来匹配行,其格式如下:
file number - page number - row number

一个非聚集索引看起来像这样:

enter image description here

你可以看到RIP书签是红色的。
一般来说,堆的行不会移动;一旦它们被插入到页面中,它们就会留在那个页面上。更精确地说,堆中的行很少移动,当它们移动时,它们会在旧位置留下一个转发地址。然而,聚集索引的行可以移动;也就是说,它们可以在数据修改或索引重组期间被重新定位到另一页。
在第二个场景中,非聚集索引使用聚集索引的索引键作为书签,而聚集索引本身应满足几个标准:
1.必须是唯一的 2.应该很短 3.应该是静态的
我将描述第一个标准(其他标准在下面的链接中描述)。
每个索引条目书签必须允许 SQL Server 找到对应于该条目的表中的一行。如果创建的聚集索引不是唯一的,则 SQL Server 将通过生成一个额外的值来使聚集索引唯一,以“打破”重复键。这个额外的值由 SQL Server 生成以创建唯一性,称为唯一标识符,并且对任何客户端应用程序都是透明的。您应该仔细考虑是否允许在聚集索引中存在重复项,原因如下:
1. 生成唯一标识符需要额外的开销。SQL Server 必须在插入时决定新行的键是否与现有行的键重复;如果是,则生成唯一标识符值添加到新行中。
2. 唯一标识符是一个无意义的信息;它是传播到表的非聚集索引中的无意义的信息。通常最好将有意义的信息传播到非聚集索引中。
整篇文章可以在这里找到。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接