我们的数据驻留在SQL Server 2008数据库中,表之间会有很多查询和连接。我们在团队内部有这样的争论,一些人争论使用整数标识更好地提高性能,一些人争论使用guid (唯一标识符)。
使用GUID作为主键时,性能真的会如此糟糕吗?
发布于 2012-03-15 20:12:43
当然,128位GUID (uniqueidentifier
)密钥比32位int
密钥大4倍。然而,它有几个关键的优点:
CAST()
调用,你甚至可以根据日期/时间范围从主键进行SELECT
。SELECT scope_identity()
在插入后获取主键的步骤。bigint
(64位)而不是int
。一旦你这样做了,GUID只有bigint
.uniqueidentifier
如何从磁盘加载页面,以及处理器现在大多是64位的,仅仅因为一个数字是128位而不是32位并不意味着比较所需的时间增加了4倍。我看到的最后一个测试显示GUID几乎同样快。最后,通过使用整数挤出一些小的性能优势可能不值得失去GUID的优势。从经验上测试它,然后自己决定。
就我个人而言,我仍然会根据情况使用这两种方法,但在我的情况下,决定因素从来没有真正归结为性能。
发布于 2012-03-15 21:37:23
我个人使用INT IDENTITY
作为我的大多数主键和集群键。
您需要将主键分开,这是一个逻辑结构-它唯一地标识您的行,它必须是唯一的、稳定的和NOT NULL
的。GUID也适用于主键-因为它被保证是唯一的。如果您使用SQL Server复制,则GUID作为主键是一个很好的选择,因为在这种情况下,您无论如何都需要一个唯一标识GUID列。
SQL Server中的集群关键字是一种物理结构,用于数据的物理排序,要正确处理要困难得多。通常,SQL Server上的索引女王Kimberly Tripp还要求一个好的聚集键是唯一的、稳定的、尽可能窄的,并且理想情况下是不断增加的(所有这些都是INT IDENTITY
)。
在这里查看她关于索引的文章:
也可以看看吉米·尼尔森的The Cost of GUIDs as Primary Key
GUID对于聚集键来说是一个非常糟糕的选择,因为它是广泛的,完全随机的,因此会导致糟糕的索引碎片和糟糕的性能。此外,聚类关键字行也存储在每个非聚集(附加)索引的每个条目中,所以您真的希望保持它很小- GUID是16字节,INT是4字节,并且有几个非聚集索引和数百万行,这会产生巨大的差异。
在SQL Server中,默认情况下,您的主键是您的聚集键-但它不是必须的。您可以很容易地使用GUID作为您的非集群主键,并使用INT IDENTITY
作为您的集群键-这只需要一点了解。
发布于 2012-03-16 04:47:51
使用GUID作为主键的一个大问题是,它们会导致大量的表碎片,这可能是一个很大的性能问题(表越大,问题就越大)。即使作为非聚集索引的键,它们也会导致索引碎片。
您可以通过设置适当的填充因子来部分缓解这个问题--但这仍然是一个问题。
大小的差异对我来说并不是很麻烦,除了那些行数很窄的表,这些表也需要表扫描。在这些情况下,每个DB页面能够容纳更多行是一种性能优势。
使用GUID可能有很好的理由,但也是有代价的。我通常更喜欢主键的INT标识,但当GUID是更好的解决方案时,我不会避免使用GUID。
https://stackoverflow.com/questions/9727090
复制