4

我在生产中有一个数据库应用程序,并且所有表使用当前设置为聚簇索引的GUID主键。由于性能考虑,我明白这是一个糟糕的设计。我一直在阅读这个话题,其中包括Kimberly Tripp的this great articleGUID主键,单独的聚簇索引列

我可以通过简单地创建INT类型的自动递增索引列并将其设置为聚集索引来改善性能吗?我从Kimberly的文章中了解到,所有非聚集索引(如我的GUID主键继续前进,如果我这样做)将引用聚集索引。但是如果我使用WHERE子句中的GUID主键搜索记录,这实际上是否会提高性能?

另外,为了获得性能增益,我是否必须按创建记录的自然顺序填充现有记录的新列?

编辑:为了解决这个问题,即是否是this other question重复:另一个问题是问一般对于性能考虑使用GUID主键的最佳实践。没有讨论具体的方法。另一方面,我的问题是要求特别是是否增加类型INT类型的自动递增索引列将有助于改善带有GUID主键的问题。此外,我的问题是问我是否必须按照“自然顺序”填充新栏目才能实现收益,而由于其较高的通用性,另一个问题也未涉及。

+0

是的,通过使用更合适的群集密钥来显着减少碎片,您的性能应该会更好。 GUID将是唯一的 - 所以你总是只提取一条记录,所以即使有一个额外的密钥查找,随着时间的推移,更好的碎片行为应该是有益的 –

+0

可能的重复[有什么使用GUID的最佳实践作为主要关键,特别是关于性能?](http:// stackoverflow。com/questions/11938044 /使用guid-as-a-key-specific-rega的最佳做法) – AHiggins

+0

@ Ahiggins - 请参阅我的编辑。 –

回答

3

有一些事情要考虑:

  1. 是你正确的,聚集索引键会出现在所有的非聚集索引。使用较小的密钥将有助于节省磁盘和缓冲池中的空间。

  2. 拥有一个身份的集群键会让你结束表插入,并可能(取决于负载)使该插入热点。现在,GUIDS是随机插入的,不会给出太多的热点,但会导致更多的页面拆分,这也可能会对性能产生不利影响。

  3. 要回答提高性能的问题,您目前的问题是什么?有任何我们可以离开的数据吗?如果您现在没有任何问题,则可能不值得更改。

  4. 当您将该列添加为标识时,它应该将其自身排序并且顺序确实无关紧要。

  5. 如果确实使用INT列作为键,请在GUID列上创建一个唯一的非聚集索引,以使优化器知道只有一个值(优化)并允许快速查找。如果它不太贵,请覆盖它。

+0

我会争辩说,“插入热点”是性能杀手比频繁页面拆分**少得多!根据我所了解的情况,热点曾经是6.5/7.0版本中的一个问题 - 不再是真的了。但页分裂是非常昂贵和杂乱的事务 - 要尽可能避免! –

+0

我发现通过删除GUID索引上的填充因子可以缓解页面拆分问题,特别是在大型表格上。删除填充因子将在页面中保留更多空间,但是您的索引开始变大。在这些情况下,我建议你可以创建一个复合自然键作为聚集索引。这会将表格排序为自然顺序。 – Namphibian

+0

@marc_s插入热点导致闩锁争用,肯定会降低性能。页面分割更糟糕,当然,但需要思考。 SQLCAT有一个分区散列表来分散热点,但有它自己的问题。 –