我正在使用SQL Server 2005(可能在不久的将来是SQL Server 2008)为一个网站创建一个新的数据库。 作为应用程序开发人员,我见过许多使用integer
(或bigint
等)作为表的ID字段以供关系使用的数据库。 但最近我也见过使用unique identifier
(GUID
) 作为ID字段的数据库。
我的问题是其中一个是否比另一个更具有优势? integer
字段在查询和联接时速度更快吗?
更新:澄清一下,这是用于表中的主键。
我正在使用SQL Server 2005(可能在不久的将来是SQL Server 2008)为一个网站创建一个新的数据库。 作为应用程序开发人员,我见过许多使用integer
(或bigint
等)作为表的ID字段以供关系使用的数据库。 但最近我也见过使用unique identifier
(GUID
) 作为ID字段的数据库。
我的问题是其中一个是否比另一个更具有优势? integer
字段在查询和联接时速度更快吗?
更新:澄清一下,这是用于表中的主键。
由于GUIDs具有高度随机性,因此作为集群键存在问题。这个问题在Paul Randal在上一期的Technet Magazine Q&A专栏中得到了解决:我想将GUID用作集群索引键,但其他人认为它会导致索引性能问题。这是真的吗?如果是,你能解释一下原因吗?
现在请记住,讨论的重点是集群索引。您说您希望使用该列作为“ID”,这不清楚是否将其用作集群键还是仅用作主键。通常两者重叠,所以我假设您希望将其用作集群索引。为什么这是一个糟糕的选择,在上面提到的文章链接中有详细说明。
对于非集群索引,GUID仍然存在一些问题,但远没有成为表左侧最重要的集群键时那么大。再次强调,GUID的随机性会导致页面分裂和碎片化,但仅限于非集群索引水平(这是一个较小的问题)。
有很多有关GUID使用的都市传说,指责它们的大小(16字节)与int(4字节)相比,并承诺如果使用它们,则会带来可怕的性能问题。这是略微夸大了。在正确设计的数据模型上,大小为16的键仍然可以是非常高效的键。虽然与int相比大4倍会导致索引中更低密度的非叶子页,但这对绝大多数表格并不是一个真正的问题。B树结构是自然平衡的树,树遍历深度很少成为问题,因此基于GUID键寻找值与基于INT键的性能类似。叶页遍历(即表扫描)不查看非叶页,并且GUID大小对页面大小的影响通常非常小,因为记录本身比GUID引入的额外12个字节要大得多。所以我会对基于“16字节vs. 4”听说建议持谨慎态度。要具体分析每种情况,决定大小对结果的影响:表中有多少其他列(即GUID大小对叶页的影响有多大),以及有多少引用正在使用它(即由于需要存储更大的外键而增加的其他表格数量)。即使使用newsequentialid()函数,GUID比int占用更多的空间并且速度较慢。如果您要进行复制或使用同步框架,则几乎必须使用GUID。
如果你一定需要一个唯一的ID,那么就使用GUID。这意味着如果你将来要合并、同步或复制数据,你应该使用GUID。
对于不太复杂的情况,int类型的ID可能已经足够了,具体取决于表格的增长大小。
像大多数情况一样,正确的答案是:这取决于具体情况。
完全同意JBrooks的观点。当您的表很大并且使用带有JOIN的SELECT语句时,特别是使用派生表时,使用GUID会显著降低性能。