使用GUID作为主键/聚簇索引

时间:2009-09-24 03:46:53

标签: sql-server uniqueidentifier sql-server-performance

我非常精通SQL服务器性能,但我不得不争辩说GUID应该用作群集主键的默认类型。

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

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

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

4 个答案:

答案 0 :(得分:8)

如果您正在进行任何类型的卷,除非您使用sequential GUIDs,否则GUID非常糟糕,因为您描述的确切原因。 Page fragmentation is severe

                 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和整数之间的this comparison显示:

  

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

但是,如果你的音量非常低,那就没那么重要了。

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

答案 1 :(得分:2)

使用GUID作为主键的缺点:

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

优点:

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

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

答案 2 :(得分:1)

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

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

我发现以下问题对于确定是否应该使用GUID非常有用。

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

答案 3 :(得分:0)

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