SQL Server索引哪些应该是群集的?

时间:2009-05-01 19:32:08

标签: sql sql-server sql-server-2005 indexing

我在某些表上有许多索引,它们都很相似,我想知道Clustered Index是否在正确的列上。以下是两个最活跃的索引的统计数据:

Nonclustered
I3_Identity (bigint)
rows: 193,781
pages: 3821
MB: 29.85
user seeks: 463,355
user_scans: 784
user_lookups: 0
updates: 256,516

Clustered Primary Key
I3_RowId (varchar(80))
rows: 193,781
pages: 24,289
MB: 189.76
user_seeks: 2,473,413
user_scans: 958
user_lookups: 463,693
updates: 2,669,261

正如你所看到的那样,经常会寻找PK,但是i3_identity专栏的所有搜索都在对这个PK进行关键查找,所以我真的从I3_Identity的索引中获益很多吗?我应该更改为使用I3_Identity作为群集吗?这可能会产生巨大的影响,因为这个表结构在我工作的地方重复了大约10000次,所以任何帮助都会受到赞赏。

5 个答案:

答案 0 :(得分:8)

弗雷德里克很好地总结了这一点,而这正是金伯利·特里普所宣扬的:集群密钥应该是稳定的(永不改变),不断增加(IDENTITY INT),小而独特。

在您的场景中,我宁愿将聚类键放在BIGINT列而不是VARCHAR(80)列上。

首先,使用BIGINT列,可以相当容易地强制执行唯一性(如果您自己不强制执行并保证唯一性,SQL Server将为您的每一行添加一个4字节的“uniquefier”)它的平均值比VARCHAR(80)小很多。

为什么尺寸如此重要?集群密钥也将被添加到EACH和每个非聚集索引中 - 所以如果你有很多行和很多非聚集索引,那么40-80字节对8字节可以很快成为巨大的区别。

另外,另一个性能提示:为了避免所谓的书签查找(从非聚集索引中的值通过聚类键进入实际数据叶页),SQL Server 2005引入了“在非聚集索引中包含“列”。这些都非常有用,而且经常被忽视。如果您的查询通常需要索引字段加上数据库中的一个或两个其他字段,请考虑包含这些字段以实现所谓的“覆盖索引”。再次 - 请参阅Kimberly Tripp的精彩文章 - 她是SQL Server Indexing Goddess! :-)她可以比我更好地解释这些东西......

总而言之:将你的聚类键放在一个小而稳定的独特专栏上 - 你会做得很好!

马克

答案 1 :(得分:5)

快速肮脏:

将聚集索引放在:

  • 一个值(几乎)永远不会改变的列

  • 新记录的值增加/减少的列 顺序

  • 执行范围的列 - 搜索

答案 2 :(得分:3)

Here's the best discussion我发现了这个话题。金伯利·特里普(Kimberly Tripp)是一名MS博主,一直处于辩论之首。我可以为你解释它,但你显然不了解基本的单词和概念,而且这篇文章具有很高的可读性。所以尽情享受!

提示:你会发现简短的答案几乎总是过于简单。

答案 3 :(得分:2)

从我过去读到的,关于索引表的两个最重要的度量是针对索引执行的查询数和索引密度。通过使用DBCC_SHOWSTATISTICS([table],[index]),您可以检查索引密度。我们的想法是,您希望在每个查询提供最多清晰度的列上使用聚簇索引。

简而言之,如果你看一下DBCC SHOW_STATISTICS的“全密度”测量并注意到这个数字非常低,这是一个很好的聚类索引。在具有更多唯一性的索引上进行聚类是有逻辑意义的,但前提是它是主动查询的。对很少使用的索引进行聚类可能弊大于利。

最后这是一个判断电话。您可能希望与您的DBA交谈并分析您的代码,以了解您将从哪里获得最大的收益。在这个有限的示例中,如果您只考虑使用情况,那么您的索引似乎会聚集在正确的区域中(即使您考虑所有密度,考虑到主键提供了您可以选择的最独特的事实。)

编辑:MSDN上有一篇非常好的文章解释了SHOW_STATISTICS为您提供的内容。我当然不是一个超级DBA,但我在这里提供的大部分信息都来自我们DBA提供的指导:)

以下是文章:http://msdn.microsoft.com/en-us/library/ms174384.aspx

答案 4 :(得分:2)

通常,当我看到对主键/群集键的键查找时,这意味着我需要在非群集键中包含(使用INCLUDE语句)更多列。查看您的查询,并查看在这些语句中选择/使用的列。如果在非群集密钥中包含这些列,则不再需要进行密钥查找。