【问题标题】:GUID primary key, separate clustered index columnGUID 主键,单独的聚集索引列
【发布时间】:2015-03-12 23:59:42
【问题描述】:

我有一个生产中的数据库应用程序,所有表都使用当前设置为聚集索引的 GUID 主键。我知道出于性能考虑,这是一个糟糕的设计。我一直在阅读有关该主题的很多内容,包括 Kimberly Tripp 的 this great article

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

另外,为了提高性能,我是否必须按照记录创建时间的自然顺序填充现有记录的新列?

编辑:要解决此问题是否与this other question 重复:另一个问题是询问有关使用 GUID 主键的性能注意事项的一般最佳实践。没有讨论具体的方法。另一方面,我的问题是询问具体是否添加 INT 类型的自动递增索引列将有助于改善 GUID 主键的问题。此外,我的问题是我是否必须按其“自然顺序”填充新列以实现收益,由于其更高的普遍性,另一个问题再次未解决。

【问题讨论】:

标签: sql-server sql-server-2008-r2 primary-key clustered-index


【解决方案1】:

有几点需要考虑:

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

  2. 拥有一个身份的聚集键将为您提供表插入的结尾,并可能(取决于负载)使其成为插入热点。现在的 GUIDS 是随机插入的,不会提供太多的热点,但会导致更多的页面拆分,这也可能对性能产生不利影响。

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

  4. 当您将列添加为 Identity 时,它应该自己播种,顺序真的不重要。

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

【讨论】:

  • 我认为与频繁的页面拆分相比,“插入热点”对性能的影响要小得多!在 6.5/7.0 版本中,热点曾经是一个问题——从我了解到的情况不再是这样了。但是页面拆分是非常昂贵和混乱的事情 - 如果可能的话,应该避免!
  • 我发现通过在 GUID 索引上删除填充因子可以在一定程度上缓解页面拆分问题,尤其是在大型表上。删除填充因子将在页面中保留更多空间,但是您的索引开始变大。在这些情况下,我建议您可以创建一个复合自然键作为聚集索引。这也会将表格排序为自然顺序。
  • @marc_s 插入热点会导致闩锁争用,这肯定会降低性能。当然,页面拆分更糟糕,但需要考虑一些事情。 SQLCAT 有一个分区哈希表来分割热点,但它也有自己的问题。
  • @Namphibian - 您绝对可以这样做,并降低 pad_index 值,以便页面拆分不会那么昂贵,但必须经常拆分根页面和中间页面。这样做的问题是,您不仅会浪费磁盘上的所有空间,还会浪费缓冲池中的所有空间。提高 IO 成本。
  • @Lijo 没有文字,我在不同数据库中发现的主要问题是由于复杂性(涉及开销)而降低 DML 性能的功能。您的里程肯定会在每个特定的应用程序和情况下有所不同,并且您的应用程序应该设计为基于该哈希进行查找,否则您几乎可以从分区中获得 0。
猜你喜欢
  • 2010-12-17
  • 2014-07-30
  • 2018-08-04
  • 1970-01-01
  • 2013-12-02
  • 2016-05-22
  • 1970-01-01
  • 2012-06-03
  • 1970-01-01
相关资源
最近更新 更多