如果您有一个在主键 (int) 上具有聚集索引的表,那么拥有一个(或多个)非聚集索引(包括该主键列作为非聚集索引中的列之一)是否是多余且不好的?
4 回答
实际上,创建与聚集索引相同的非聚集索引可能是有正当理由的。原因是聚集索引承载了行数据的包袱,这会使行密度非常差。IE。由于不在聚集键中的宽字段,每页可以有 2-3 行,但聚集索引键只有 20 个字节。在与聚集索引完全相同的键和顺序上具有非聚集索引将提供每页2-3数百个键的密度。非聚集索引可以更有效地回答 OLAP/BI 工作负载的许多典型聚合查询,这仅仅是因为它将 I/O 减少了数百倍。
至于包含部分聚集键的非聚集索引,或者甚至是相同键但顺序不同的非聚集索引,那么所有的赌注都没有了,因为它们显然可以用于大量查询。
所以你的问题的答案是:它取决于。
要获得更准确的答案,您必须共享表的确切架构和所涉及的确切查询。
是的,通常不需要,因为聚集索引的列已经添加到非聚集索引中的每个索引条目。
为什么?聚集键的值是真正允许 SQL Server“找到”一行数据的原因——它是指向实际数据的“指针”——所以很明显,它必须存储在非聚集索引中。如果您查找过“Smith, John”并且您需要了解更多关于此人的信息,您需要查看实际数据 --> 这通过在非索引节点中包含集群键的值来完成-聚集索引。
该聚集键值已经存在,因此通常再次显式地将该值添加到非聚集索引中是多余且不必要的。不好的是它只是浪费空间而没有给你任何好处。
我同意 Remus 的观点——聚集索引并不是真正的索引——它告诉你数据是如何在页面中组织的。(在您的情况下,它也是主键,但这不需要是同一件事)。非聚集索引包括该行定位器信息,所以是的,它是多余的。
但是如果一个非聚集索引在覆盖 ,并且不需要使用数据行书签,那么它的使用效率会比聚集索引高很多,而且效率随着数据行大小与非聚集索引的大小增加。
我发现,如果您对查询工作负载中的访问路径有很好的处理,有时通常可以使用一些选择性覆盖非聚集索引来完全消除集群选择——堆表、PK 和一些好的非聚集索引。 -聚集索引,你就完成了。
没有 100% 的答案,但答案几乎是肯定的。
其他索引用于帮助连接和排序(通常)。鉴于主键已经被索引,如果优化器可以基于它加入,它将使用它。
如果从连接/排序的角度来看需要另一个索引,那么在索引组合中包含 PK 会提供哪些额外帮助?以前PK不能加入,现在也加入不了。而且它也不会真正帮助任何人进行排序。