我们的数据驻留在SQL Server 2008数据库中,表之间会有很多查询和连接。我们在团队内部有这个论点,有些人认为使用整数身份对性能更好,有些人则主张使用guid(唯一标识符)。
使用GUID作为主键,性能是否真的遭受了严重影响?
答案 0 :(得分:31)
128位GUID(uniqueidentifier
)密钥当然比32位int
密钥大4倍。但是,有一些关键优势:
SELECT
来电,您甚至可以根据日期/时间范围从主键CAST()
{。}}。SELECT scope_identity()
在插入后获取主键的步骤。bigint
(64位)而不是int
。完成后,uniqueidentifier
只是bigint
的两倍。最后,通过使用整数来挤出一些小的性能优势可能不值得失去GUID的优势。根据经验进行测试并自行决定。
就个人而言,我仍然会根据具体情况使用两者,但在我的情况下,决定因素从未真正降低到表现。
答案 1 :(得分:20)
我个人使用INT IDENTITY
来处理我的主要和群集密钥。
您需要将主键分开,这是一个逻辑结构 - 它唯一标识您的行,它必须是唯一且稳定的NOT NULL
。 GUID也适用于主键 - 因为它保证是唯一的。如果使用SQL Server复制,GUID作为主键是一个不错的选择,因为在这种情况下,无论如何都需要唯一标识的GUID列。
SQL Server中的集群密钥是一个物理结构,用于数据的物理排序,并且更难以正确使用。通常情况下,SQL Server上的索引女王Kimberly Tripp也需要一个好的集群密钥才能是唯一的,稳定的,尽可能地缩小,并且理想情况下不断增加(所有这些都是INT IDENTITY
)。
请参阅她关于索引的文章:
还可以看到Jimmy Nilsson的The Cost of GUIDs as Primary Key
GUID是群集密钥的一个非常糟糕的选择,因为它很宽,完全随机,因此导致错误的索引碎片和糟糕的性能。此外,群集密钥行也存储在每个非群集(附加)索引的每个条目中,因此您确实希望保持较小 - GUID为16字节,而INT为4字节,并且有几个非聚集索引和几百万行,这会产生巨大的差异。
在SQL Server中,您的主键默认情况下是您的群集密钥 - 但它不一定是。您可以轻松地将GUID用作非群集主键,并使用INT IDENTITY
作为群集密钥 - 只需要了解一点。
答案 2 :(得分:4)
答案 3 :(得分:3)
GUID作为主键的一个大问题是它们会导致大量的表碎片,这可能是一个很大的性能问题(表越大,问题就越大)。即使作为非聚簇索引的键,它们也会导致索引碎片化。
您可以通过设置适当的填充因子来部分缓解问题 - 但这仍然是一个问题。
除了需要进行表扫描的其他窄行表外,大小差异并没有那么多。在这些情况下,每个数据库页面能够容纳更多行是一个性能优势。
使用GUID有充分的理由,但也有成本。我通常更喜欢INT IDENTITY用于主键,但是当它们是更好的解决方案时我不会避免使用GUID。
答案 4 :(得分:0)
使用GUID的主要优点是它们在所有空间和时间都是唯一的。
使用GUID作为键值的主要缺点是它们是 大。弹出的是16个字节,它们是SQL中最大的数据类型之一 服务器。构建在GUID上的索引将比大于和慢 构建在IDENTITY列上的索引,通常是整数(4个字节)。
因此,对于需要合并来自多个来源的数据的情况,它们是一个很好的解决方案
来源:http://www.sqlteam.com/article/uniqueidentifier-vs-identity
答案 5 :(得分:-1)
如果数据库表记录可以增长到百万条记录,我认为将它用作主键并不是一个好主意。