我相当精通 SQL Server 性能,但我总是不得不反对 GUID 应该用作集群主键的默认类型的想法。

假设该表每天的插入量相当低(5000 +/- 行/天),我们会遇到什么样的性能问题?页面分割将如何影响我们的查找性能?我应该多久重新索引一次(或者应该进行碎片整理)?我应该将填充因子设置为多少(100、90、80 等)?

如果我每天插入 1,000,000 行怎么办?

我预先对所有问题表示歉意,但我希望获得一些支持,以防止不使用 GUID 作为 PK 的默认值。然而,我完全愿意通过 StackOverflow 用户群的压倒性知识来改变我的想法。

有帮助吗?

解决方案

如果您要做任何类型的卷,除非您使用 顺序指导, ,出于您描述的确切原因。 页面碎片很严重:

                 Average                    Average
                 Fragmentation  Fragment    Fragment   Page     Average 
Type             in Percent     Count       Size       Count    Space Used

id               4.35           7           16.43      115      99.89
newidguid        98.77          162         1          162      70.90 
newsequentualid  4.35           7           16.43      115      99.89

并作为 此比较 在GUID和整数之间显示:

test1引起了大量的页面拆分,并在周围有扫描密度 12% 插入完成后,当我运行DBCC ShowContig时。 Test2表的扫描密度约为98%

但是,如果您的音量非常低,那就没关系了。

如果您确实确实需要一个全球唯一的ID,但具有较高的音量(并且不能使用顺序ID),只需将GUID放入索引列中即可。

其他提示

使用GUID作为主要密钥的缺点:

  • 没有有意义的订购,意味着索引不会像整数那样提供性能提升。
  • GUID 16字节的大小,与整数相比2、4或8个字节。
  • 人类很难记住,所以作为参考ID不好。

优点:

  • 允许在网页查询字符串或应用程序中显示时可能会减少危险的不可能的主键。
  • 在不提供自动增量或身份数据类型的数据库中有用。
  • 当您需要在平台或环境之间连接两个不同数据源之间的数据时,很有用。

我认为关于是否使用GUIDS的决定很简单,但也许我没有意识到其他问题。

由于每天的插入量如此之低,我怀疑页面分割应该是一个重要因素。真正的问题是如何将 5,000 与现有行数进行比较,因为这将是决定适当的初始填充因子以延迟拆分所需的主要信息。

也就是说,我个人并不是 GUID 的忠实粉丝。我知道它们在某些情况下可以很好地发挥作用,但在许多情况下它们只是“妨碍”[效率、易用性、……]

我发现以下问题有助于缩小决定是否应使用 GUID 的范围。

  • PK会被分享/发布吗?(IE。它是否会在 SQL 内部使用之外使用,应用程序是否会以某种持久的方式需要这些键?用户会以某种方式看到这些密钥吗?
  • PK 可以用来帮助合并不同的数据源吗?
  • 该表是否具有由数据中的列组成的主表(可能是复合表)?这个密钥可能有多大
  • 主键如何排序?如果是复合的,前几列是否具有选择性?

使用GUID(除非是顺序的GUID)作为聚类索引将杀死插入性能。由于物理表布局根据聚类索引对齐,因此使用具有随机测序顺序的GUID会导致严重的表碎片化。如果要将GUID用作PK/群集索引,则必须使用SQL Server中的NewSequentionId()函数是顺序GUID。这将确保生成的指南被顺序排序并防止碎片化。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top