2010-04-09 42 views
5

我们有一个数据库,其中所有的PK都是GUID,大多数PK也是表的聚集索引。我们知道这是不好的(由于GUID的随机性)。所以,看起来这里基本上有两种选择(尽量不要把GUID全部扔出去,这是我们不能做的(至少现在不行))。具有群集GUID PK的SQL Server数据库 - 切换聚簇索引或切换到顺序(梳)GUID?

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

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

有问题的应用程序有500多个表格,最大的一个目前大约有一百五十万行,几个表格大约有五十万行,其余大大低于大多数(大部分远低于10K)。

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

谢谢!

回答

3

如果:

为什么GUID的是坏在SQL Server这里聚集键退房金佰利特里普的优秀系列你可以改变你的那么这很可能是你的快速胜出选项。顺序guid将停止表中的碎片,同时保留为聚簇索引。然而,连续引导的主要缺点是,它们随后变得可以猜测,而这往往是不希望的,并且首先使用guid的原因。

如果你沿着你的群集主键的Identity路径,然后只是你的GUID列上的索引,那么你仍然会在你的GUID索引中得到很多碎片。然而,桌子不再分散的事实将是一个巨大的收益。

最后,虽然我知道你说你现在不能这样做,但是,如果你不需要使用GUID作为索引,那么你可以删除所有这些问题。

+0

谢谢你的回答。简单的评论/澄清:我不关心GUID的可猜测性,只关心它们在整个安装过程中的独特性。 – Eyvind 2010-04-09 09:17:07

+0

然后,只需将您的guid更改为像SQLSEQ中的NEWSEQUENTIALID()这样的连续GUID,就可以解决大部分即时问题。但是,不要将完全重新考虑因素放入身份中,而不能超过必要时间。 – 2010-04-09 09:26:17

+0

因此,考虑到我们选择了连续的GUID:对于在许多表格中有100K行的客户呢?这样的改变会使他们受益,还是情况会和今天一样糟糕,因为表格和索引已经是充满“随机”数据? – Eyvind 2010-04-09 10:51:59

7

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

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

顺序GUID的绝对是一个比普通的随机GUID好很多,但仍然比INT(16比4个字节)大4倍,如果你的表中有很多行,并且这张表上有很多非聚集索引,这也是一个因素。群集密钥正被添加到每个非聚簇索引中,因此会显着增加16个字节和4个字节大小的负面影响。更多的字节意味着磁盘和SQL Server RAM中的页面更多,因此更多的磁盘I/O和更多的SQL Server工作。

在适当情况下,您肯定可以将GUID保留为主键 - 但在这种情况下,我强烈建议在该表中添加一个单独的INT IDENTITY,并使该INT成为集群密钥。我自己用很多大表来完成这个工作,结果令人惊讶 - 表碎片从99%降到了百分之几,性能也好多了。

马克

相关问题