Sql server 具有群集GUID PKs的SQL Server数据库-切换群集索引还是切换到顺序(comb)GUID?

Sql server 具有群集GUID PKs的SQL Server数据库-切换群集索引还是切换到顺序(comb)GUID?,sql-server,guid,uniqueidentifier,clustered-index,Sql Server,Guid,Uniqueidentifier,Clustered Index,我们有一个数据库,其中所有的PK都是GUID,大多数PK也是表的聚集索引。我们知道这是不好的(由于guid的随机性)。因此,这里似乎基本上有两种选择(除了把guid作为PKs一起扔掉,这是我们无法做到的(至少现在不行)) 我们可以将GUID生成算法更改为NHibernate使用的算法,如中所述,或 对于使用量最大的表,我们可以更改为不同的聚集索引,例如标识列,并将“随机”guid保留为PKs 在这种情况下,是否有可能给出一般性建议 所讨论的应用程序有500多个表,其中最大的一个表目前大约有1

我们有一个数据库,其中所有的PK都是GUID,大多数PK也是表的聚集索引。我们知道这是不好的(由于guid的随机性)。因此,这里似乎基本上有两种选择(除了把guid作为PKs一起扔掉,这是我们无法做到的(至少现在不行))

  • 我们可以将GUID生成算法更改为NHibernate使用的算法,如中所述,或
  • 对于使用量最大的表,我们可以更改为不同的聚集索引,例如标识列,并将“随机”guid保留为PKs
在这种情况下,是否有可能给出一般性建议

所讨论的应用程序有500多个表,其中最大的一个表目前大约有150万行,少数表大约有50万行,其余的表则要低得多(大多数都远低于10K)

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


谢谢

我的观点很清楚:使用INT标识作为集群键。这是迄今为止最好、最优化的聚类键,因为它:

  • 小的
  • 稳定(永不改变)
  • 独特的
  • 不断增加
顺序GUID肯定比常规随机GUID好得多,但仍然比INT(16对4字节)大四倍,如果表中有很多行,并且该表上也有很多非聚集索引,这将是一个因素。每个非聚集索引中都添加了聚集键,这样就显著增加了大小为16字节对4字节的负面影响。更多字节意味着磁盘上和SQL Server RAM中的页面更多,因此SQL Server需要更多的磁盘I/O和更多的工作

在适当的情况下,您完全可以将GUID保留为主键,但在这种情况下,我强烈建议向该表添加一个单独的INT标识,并将该INT作为集群键。我自己用大量的大型表完成了这项工作,结果令人惊讶——表碎片率从99%以上下降到了几%,而且性能更好

请查看Kimberly Tripp关于为什么GUID在SQL Server中作为群集键不好的优秀系列:


Marc

如果您能够轻松地将guid生成更改为顺序guid生成,那么这可能是您的快速获胜选项。顺序guid将停止表上的碎片,同时保留为聚集索引。但是,顺序guid的主要缺点是,它们会变得容易猜测,这通常是不需要的,而且首先使用guid的原因是

如果您使用集群主键的标识路径,然后只使用guid列上的一个索引,那么guid索引上仍然会出现大量碎片。然而,该表不再支离破碎的事实将是一个巨大的收益


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

谢谢你的回答。只是一个简短的评论/澄清:我不关心guid的可猜测性,只关心它们在安装过程中的唯一性。然后,只需将您的guid更改为顺序guid,如SQL Server中的NEWSEQUENTIALID(),就可以解决大多数眼前的问题。但是,不要推迟对标识进行完整的重新考虑。因此,考虑到我们选择了顺序GUID:对于在许多表中有100K行的客户来说,这样的更改会使他们受益吗?还是情况会像今天一样糟糕,因为表和索引已经充满了“随机”属性数据?一旦您重建索引,情况就会改善,并且将使用顺序guid进行后续插入。看见