COMB GUID的性能价值

14

Jimmy Nilsson讨论了他的COMB guid概念,此处有详细介绍。在NHibernate等其他领域,这个概念因其相对于通常更为随机的标准GUID具有性能价值而受到欢迎。

然而,在测试中,这似乎并非如此。我有所遗漏吗?

测试用例:

我有一个名为temp的表(不是临时表,只是一个名为“temp”的表),其中有585,000行记录。我有一个新表称为Codes,并希望将temp表中的所有585,000个代码值复制到codes表中。我执行的测试SQL是:

set statistics time on;

truncate table codes;
DBCC DBREINDEX ('codes', '', 90);

insert into codes (codeid, codevalue)
select newid(), codevalue from temp

truncate table codes;
DBCC DBREINDEX ('codes', '', 90);

insert into codes (codeid, codevalue)
select CAST(CAST(NEWID() AS BINARY(10)) + CAST(GETDATE() AS BINARY(6)) AS UNIQUEIDENTIFIER), codevalue from temp

使用标准GUID值的性能:

SQL Server执行时间:CPU 时间=17250毫秒,耗时=15735 毫秒。

(影响了585000行)

使用COMB GUID值的性能:

SQL Server执行时间:CPU 时间=17500毫秒,耗时=16419 毫秒。

(影响了585000行)

我错过了什么?使用COMB GUID值稍微增加了一些时间,这可能是由于额外的转换。我以为通过使用最后6个字节的日期对GUID进行半排序来减少插入时间,但是性能提升似乎不存在。


我的回答或其他回答是否解决了你的问题? - gbn
@Chris:gbn 正确吗? - jgauffin
3个回答

16
我建议您没有看到排序好处的原因是目标表没有主键。所以,您看到的是转换开销。如果它有一个主键,那么这585,000行必须在插入时进行排序。 SQL如何知道它是半排序的?
现在,如果它是5,850 x 100行插入,那么您可能会看到一些好处,因为新行将“在末尾”而不是“在中间”,从而减少页面分裂和开销。
我进一步说,该文章日期为2002年,适用于SQL 2000,并已被现实取代。
在SQL Server 2005中,我们有SEQUENTIAL GUID,允许严格单调的GUID解决某些问题。 GUID作为PK也已经在此处完成:最近的例子:数据库中的INT vs Unique-Identifier for ID field带有第三方链接。
如果ORM规定GUID作为PK而不是自然键或标准基于int的代理键,则这是ORM的严重限制。并且是客户端尾部摇摆数据库狗的情况。

7

我的意见是,只有在Guid列上有索引(主键、外键或其他类型的索引,聚集或非聚集)时,您才会看到差异,因为标准GUID与NewGuid或Comb GUID之间成本的差别是由于每次执行插入时重新排序索引数据的高成本。

请参见我的问题,其中我使用一些来自SQL Server和Oracle的真实数据证实了这一点。


-2

你生成新GUID的代码有问题。对于每一行,它都创建了一个非常不同的数字(为每一行调用NEWID())。你需要保持大部分GUID相同。


codeId是表的关键,因此必须不同。如果您考虑使用COMB guid,则需要使第一部分随机以防止插入时发生键冲突,这些插入都在计时器分辨率内(大约为300ms)。 SQL guid的排序顺序首先按最后6个元素进行,因此将这些元素作为从datetime生成的升序数字可以保留条目进入索引的顺序。 - Alex White

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接