【发布时间】:2014-04-09 17:29:25
【问题描述】:
感谢精彩的文章The Cost of GUIDs as Primary Keys,我们有了 COMB GUID。根据目前的实现,有两种方法:
- 使用最后 6 个字节作为时间戳:GUIDs as fast primary keys under multiple databases
- 通过使用 windows 刻度使用最后 8 个字节作为时间戳:GUID COMB strategy in EF4.1 (CodeFirst)
我们都知道,对于 GUID 的 6 字节时间戳,随机字节会有更多字节,以减少 GUID 的冲突。但是,将创建更多具有相同时间戳的 GUID,并且这些 GUID 根本不是连续的。这样,8 字节的时间戳将是首选。
所以这似乎是一个艰难的选择。根据上面GUIDs as fast primary keys under multiple databases的文章,它说:
在我们继续之前,关于这种方法的简短脚注:使用 1 毫秒分辨率的时间戳意味着非常接近生成的 GUID 可能具有相同的时间戳值,因此不会是连续的。这对于某些应用程序来说可能很常见,实际上我尝试了一些替代方法,例如使用更高分辨率的计时器,例如 System.Diagnostics.Stopwatch,或者将时间戳与可以保证顺序的“计数器”结合使用一直持续到时间戳更新。然而,在测试过程中,我发现这根本没有明显的区别,即使在同一个一毫秒窗口内生成了数十甚至数百个 GUID。这也与 Jimmy Nilsson 在测试 COMB 时遇到的情况一致
只是想知道了解数据库内部的人是否可以分享一些关于上述观察的信息。是因为该数据库服务器只是将数据存储在内存中,并且只有在达到某个阈值时才写入磁盘?因此,具有相同时间戳的非序列 GUID 的插入数据的重新排序通常会发生在内存中,因此性能损失最小。
更新: 根据我们的测试,与随机 GUID 相比,COMB GUID 无法减少在 Internet 上声称的表碎片。现在似乎唯一的方法是使用 SQL Server 生成顺序 GUID。
【问题讨论】:
-
我认为列出的所有文章都将主键与聚集索引键混淆了。 GUIDS 可以很好地用作主键,尤其是在多主键的情况下,但不能很好地用作聚集索引键(尽管“不能很好地工作”取决于表中还有哪些其他列)。
-
是的,你是对的。我们主要担心的是,由于 GUID 的随机性,它会在我们的表中聚集 PK,从而产生大量碎片。关于我上面关于同一时间戳内随机 GUID 性能的问题有什么想法吗?
-
如果没有其他列可用作聚集索引键,那么我会选择
newsequentialid()(来自下面的@ErikE)。
标签: sql-server database guid