8

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

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

如果我每天插入 1,000,000 行会怎样?

我为所有问题预先道歉,但我希望得到一些备份,因为我没有使用 GUID 作为 PK 的默认值。然而,我完全愿意让 StackOverflow 用户群的大量知识改变我的想法。

4

4 回答 4

8

如果您正在执行任何类型的卷,除非您使用顺序 GUID ,否则 GUID 非常糟糕,因为您描述的确切原因是 PK 错误。页面碎片严重

                 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 和整数之间的比较所示:

当我在插入完成后运行 DBCC SHOWCONTIG 时,Test1 导致了大量的页面拆分,并且扫描密度约为12% 。Test2 表的扫描密度约为 98%

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

如果您确实需要一个全局唯一 ID 但容量很大(并且不能使用顺序 ID),只需将 GUID 放在索引列中即可。

于 2009-09-24T04:00:50.980 回答
2

使用 GUID 作为主键的缺点:

  • 没有有意义的排序,意味着索引不会像使用整数那样提高性能。
  • GUID 的大小为 16 个字节,而整数则为 2、4 或 8 个字节。
  • 人类很难记住,所以作为参考 id 不好。

好处:

  • 允许不可猜测的主键,因此在网页查询字符串或应用程序中显示时危险性较小。
  • 在不提供自动增量或标识数据类型的数据库中很有用。
  • 当您需要跨平台或环境连接两个不同数据源之间的数据时很有用。

我认为是否使用 GUID 的决定非常简单,但也许我不知道其他问题。

于 2009-09-24T03:58:34.203 回答
1

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

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

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

  • PK 会被共享/发布吗?(即,它会在 SQL 内部使用之外使用吗?应用程序是否需要以某种持久的方式使用这些键?用户会以某种方式看到这些键吗?
  • PK 可以用来帮助合并不同的数据源吗?
  • 该表是否有一个由数据中的列组成的主要(可能是复合)?这个可能这个键的大小是多少
  • 主键如何排序?如果是复合的,前几列是选择性的吗?
于 2009-09-24T04:00:45.380 回答
0

使用 guid(除非它是顺序 GUID)作为聚集索引会降低插入性能。由于物理表布局是根据聚集索引对齐的,使用具有随机排序顺序的 guid 会导致严重的表碎片。如果要将 guid 用作 PK/聚集索引,它必须是使用 sql server 中的 newsequentialid() 函数的顺序 guid。这将保证生成的 guid 按顺序排序并防止碎片。

于 2009-09-24T04:05:55.313 回答