newid()vs newsequentialid()有什么区别/利弊?

时间:2009-10-19 06:08:45

标签: sql-server-2005 primary-key identity

在所有主键都是GUID的数据库中,使用newid()与newsequentialid()作为“默认值或绑定”的差异/含义和/或利弊是什么。

我所知道的唯一区别是newid()创建了一个新的随机GUID而不是newsequentialid()以递增的方式基于表中的最后一个GUID创建一个新的GUID。

4 个答案:

答案 0 :(得分:28)

据我了解,当你在DB中连续执行插入时,它将按照相对于表中其他PK的顺序插入。使用普通的guid,这可能是表中的任何位置。 newsequentialid()将始终添加到表的末尾。

因此改进了插件的性能。

This site解释了两种不同方法之间的差异和基准。

更新 - 引用的博客文章已被移动。该链接现在指的是web.archive.org链接。这是关键点:

enter image description here

  

最引人注目的是NEWID系统功能所需的写入次数。这与平均页面密度69%相结合,证明了页面分裂是由叶片上插入物的随机分布引起的。页面填满后,需要将其分成2页,每页50%,以完成插入。不仅页面拆分导致页面密度差,而且数据页面碎片非常严重(下一个数据页面不在当前页面旁边的可能性为99%)。在我们的测试中,页面拆分所需的免费页面的最可能位置是在表的末尾,而不管插入行的位置。因此,要按顺序读取行,扫描需要在广泛分布的分页之间来回跳转,因此是令人震惊的碎片。

- Stefan Delmarco

答案 1 :(得分:13)

关于顺序键的使用(与identity,sequence和NEWSEQUENTIALID一样)与非顺序键(如NEWID或自定义随机密钥生成器)的使用,有几个方面需要考虑。

从顺序键开始,所有行都进入索引的右端。当页面已满时,SQL Server会分配一个新页面并填充它。这导致索引中的碎片更少,这有利于读取性能。此外,当单个会话加载数据时,插入可以更快,并且数据驻留在单个驱动器或少量驱动器上。

但是,对于拥有多个主轴的高端存储子系统,情况可能会有所不同。从多个会话加载数据时,最终会出现页面锁存器争用(锁存器是用于同步对数据库页面的访问的对象)与索引叶级别链接列表的最右侧页面。此瓶颈阻止使用存储子系统的完整吞吐量。 请注意,如果您决定使用顺序键并且使用数字键,则始终可以从类型中的最小值开始以使用整个范围。例如,不是在INT类型中以1开头,而是从-2,147,483,648开始。

考虑非顺序密钥,例如使用NEWID或自定义解决方案生成的随机密钥。当试图强行进入已经完整的页面时,SQL Server执行经典页面拆分 - 它分配一个新页面并将一半的行从原始页面移动到新页面。页面拆分有成本,加上导致索引碎片。索引碎片可能会对读取性能产生负面影响。但是,就插入性能而言,如果存储子系统包含许多心轴并且您正在从多个会话加载数据,则无论顺序如何,随机顺序实际上可能优于顺序。

那是因为索引的右端没有热点,你使用的是存储子系统 可用吞吐量更好。 Thomas Kejser在http://blog.kejser.org/2011/10/05/boosting-insert-speed-by-generating-scalable-keys/的博客中可以找到演示此策略的基准测试的一个很好的例子。

<强>来源: 查询Microsoft® SQLServer®2012 考试70-461 培训套件

答案 2 :(得分:1)

根据我的理解,当SQL实例启动时,NEWSEQUENTIALID GUID被初始化为随机值。然后,对于其操作的生命周期,GUID在中央GUID上递增,而不是通过查看为表生成的最后一个GUID。

答案 3 :(得分:-3)

据我所知,NEWID()按随机顺序生成GUIDNEWSEQUENTIALID()按顺序生成GUIDNEWSEQUENTIALID()只能在表的default子句中使用。