具有群集GUID PK的SQL Server数据库 - 切换聚簇索引还是切换到顺序(梳状)GUID?

时间:2010-04-09 08:51:33

标签: sql-server guid uniqueidentifier clustered-index

我们有一个数据库,其中所有PK都是GUID,大多数PK也是表的聚簇索引。我们知道这很糟糕(由于GUID的随机性)。所以,似乎这里基本上有两个选项(不过将GUID作为PK完全丢弃,我们做不到(至少目前不行))。

  • 我们可以将GUID生成算法更改为例如NHibernate使用的那个,详见this post
  • 对于使用最多的表,我们可以更改为不同的聚簇索引,例如: IDENTITY列,并将“随机”GUID保留为PK。

是否可以在这种情况下提供任何一般性建议?

该应用程序有500多个表,最大的一个目前约150万行,几个表约50万行,其余表显着降低(大多数低于10K)。

此外,该应用程序已安装在多个客户站点,因此我们必须考虑现有客户的任何可能的负面影响。

谢谢!

2 个答案:

答案 0 :(得分:7)

我的观点很明确:对集群密钥使用INT IDENTITY。这是迄今为止最好,最优化的聚类键,因为它:

  • 稳定(绝不应该改变)
  • 独特
  • 不断增加

顺序GUID肯定比常规随机GUID要好很多,但是仍然比INT大16倍(16对4字节),如果你的表中有很多行,这将是一个很大的因素该表上的聚集索引也是如此。聚类键被添加到每个非聚集索引中,因此显着增加了16个大小与4个字节的负面影响。更多字节意味着磁盘和SQL Server RAM中的页面越多,因此更多的磁盘I / O和更多的SQL Server工作。

在适当的情况下,您绝对可以将GUID保留为主键 - 但在这种情况下,我强烈建议为该表添加单独的INT IDENTITY,并使该INT成为群集密钥。我自己已经完成了许多大型表格,结果令人惊讶 - 表格碎片率从99%降低到百分之几,性能更好。

查看Kimberly Tripp关于为什么GUID在SQL Server中作为群集密钥出错的优秀系列:

马克

答案 1 :(得分:3)

如果你能够轻松地将你的guid生成改为顺序guid生成,那么这可能是你的快速获胜选择。顺序guid将停止表上的碎片,同时保留为聚簇索引。顺序guid的主要缺点是它们然后变得可猜测,这通常是不可取的,并且首先使用guid的原因。

如果您沿着集群主键的Identity路由,然后只是guid列的索引,那么您的guid索引仍然会有很多碎片。然而,表格将不再分散的事实将是一个巨大的收获。

最后,我知道你说你现在不能这样做,但是,如果你根本不需要使用guid作为索引,那么你就可以解决所有这些问题。