我正在使用SQL Server 2005(可能在不久的将来使用SQL Server 2008)为网站创建一个新数据库。作为应用程序开发人员,我见过很多数据库使用integer
(或bigint
等)来表示将用于关系的表的ID字段。但最近我也看到了使用unique identifier
(GUID
)作为ID字段的数据库。
我的问题是,一个人是否优于另一个人?查询和加入等integer
字段会更快吗?
更新:为清楚起见,这是表格中的主键。
答案 0 :(得分:52)
由于随机性较高,GUID作为群集密钥存在问题。 Paul Randal在上一期Technet杂志Q& A专栏中解决了这个问题:I'd like to use a GUID as the clustered index key, but the others are arguing that it can lead to performance issues with indexes. Is this true and, if so, can you explain why?
现在请记住,讨论具体是关于群集索引。您说您希望将该列用作“ID”,如果您将其表示为群集密钥或仅仅是主键,则不清楚。通常两者重叠,所以我假设你想将它用作聚簇索引。在上面提到的文章的链接中解释了为什么这是一个糟糕的选择的原因。
对于非聚簇索引,GUID仍然存在一些问题,但不像它们是表的最左侧聚簇键时那么大。同样,GUID的随机性引入了页面拆分和碎片,只是在非聚集索引级别(一个小得多的问题)。
围绕GUID使用的许多城市传说基于它们的大小(16字节)与int(4字节)相比谴责它们并且如果使用它们则承诺可怕的性能厄运。这有点夸张。在正确设计的数据模型上,16号键可以是一个非常有用的键。虽然如果它是int的4倍大,会导致索引中的低密度非叶页更多,这对绝大多数表来说并不是真正的问题。 b树结构是一个自然平衡的树,树遍历的深度很少成为问题,因此基于GUID键而不是INT键寻找值在性能上是相似的。叶页遍历(即表扫描)不查看非叶页,GUID大小对页面大小的影响通常非常小,因为记录本身明显大于引入的额外12个字节由GUID。因此,我会采用基于'16字节对4'的听说建议,使用相当大的盐。逐个案例分析个案,并确定大小影响是否真正产生影响:表中有多少其他列(即叶子页面上GUID大小有多大影响)和多少引用正在使用它(即,由于需要存储更大的外键,因此将增加多少其他表)。
我正在以一种临时防御GUID的方式调出所有这些细节,因为他们最近收到了很多不好的报道,有些是不应该的。它们有其优点,在任何分布式系统中都是必不可少的(当你谈论数据移动时,无论是通过复制或同步框架还是其他)。我看到根据GUID在没有适当考虑的情况下避开的不良声誉做出的错误决定。但确实如此,如果你必须使用GUID作为集群密钥,请确保解决随机性问题:尽可能使用顺序guid 。
最后,要回答您的问题:如果您没有使用GUID的特定原因,请使用INT。
答案 1 :(得分:8)
即使您使用newsequentialid()函数,GUID也会占用更多空间并且比int慢。如果您要复制或使用同步框架,您几乎必须使用guid。
答案 2 :(得分:6)
INT是4个字节,BIGINT是8个字节,GUIDS是16个字节。表示数据所需的空间越多,处理数据所需的资源就越多 - 磁盘空间,内存等。因此(a)它们的速度较慢,但(b)这可能只是因为卷是一个问题(数百万)在非常非常短的时间内进行行或数千次交易。)
GUID的优势在于它们(几乎)是全球唯一的。使用正确的算法生成一个guid(并且SQL Server xxxx将使用正确的算法),并且没有两个guid将是相似的 - 无论生成它们的计算机有多少,无论多么频繁。 (这在使用72年后不适用 - 我忘记了细节。)
如果您需要跨多个服务器生成唯一标识符,则GUID可能很有用。如果你需要mondo perforance和不到20亿的价值,那么整数可能就好了。最后也许最重要的是,如果您的数据具有自然键,请坚持使用它们并忘记代理值。
答案 3 :(得分:4)
如果你肯定,绝对必须有一个唯一的ID,然后是GUID。这意味着如果您要合并,同步,复制,您可能应该使用GUID。
对于不太健壮的东西,int应该足够,这取决于表的增长程度。
在大多数情况下,正确的答案是,这取决于。
答案 4 :(得分:3)
答案 5 :(得分:2)
完全同意JBrooks。 我想说当你的表很大,并且你使用带有JOINS的选择时,特别是对于派生表,使用GUID会显着降低性能。