SQL Server 2012Sequence
作为一项新功能而引入,与Oracle和Postgres中的相同。序列优先于身份何处?为什么我们需要序列?
Answers:
我想你会在这里找到答案
使用一列的identity属性,您可以轻松生成自动递增的数字(通常用作主键)。使用Sequence,它将是一个不同的对象,您可以在插入时将其附加到表列。与身份不同,列值的下一个数字将从内存而不是从磁盘中检索-这使Sequence大大快于Identity。我们将在接下来的示例中看到这一点。
而在这里:
序列:序列已被SQL Server社区要求多年,并且已包含在此版本中。序列是用户定义的对象,它生成数字序列。这是使用序列的示例。
还有这里:
SQL Server序列对象生成数字序列,就像sql表中的标识列一样。但是序列号的优点是序列号对象不限于单个sql表。
在msdn上,您还可以阅读有关用法以及我们为什么需要它的更多信息(此处):
序列是用户定义的模式绑定对象,该对象根据创建序列的规范生成数字值序列。数值序列按定义的时间间隔以升序或降序生成,并且可以按要求循环(重复)。与标识列不同,序列不与表关联。应用程序引用序列对象以接收其下一个值。序列和表之间的关系由应用程序控制。用户应用程序可以引用序列对象,并跨多个行和表协调值键。
使用CREATE SEQUENCE语句可独立于表创建序列。使用选项,您可以控制增量,最大值和最小值,起点,自动重启功能以及缓存以提高性能。有关选项的信息,请参见CREATE SEQUENCE。
与插入行时生成的标识列值不同,应用程序可以通过调用NEXT VALUE FOR函数在插入行之前获取下一个序列号。即使从未将序号插入表中,当调用NEXT VALUE FOR时也会分配序号。NEXT VALUE FOR函数可以用作表定义中列的默认值。使用sp_sequence_get_range一次获取多个序列号的范围。
序列可以定义为任何整数数据类型。如果未指定数据类型,则序列默认为bigint。
尽管序列比标识列提供更大的灵活性,但我发现它们没有任何性能优势。
我发现使用身份的性能始终比使用批处理插入序列快3倍。
我插入了约150万行,性能为:
我通过表默认值将行插入到使用序列对象的表中:
NEXT VALUE for <seq> for <col_name>
并尝试在select语句中指定序列值:
SELECT NEXT VALUE for <seq>, <other columns> from <table>
两者都是比同一方法慢的相同因素。我为序列使用了默认的缓存选项。
Arion第一个链接中引用的文章显示了逐行插入的性能,同一性和序列之间的差异对于10,000个插入为16.6秒至14.3秒。
高速缓存选项对性能有很大影响,但是对于较大的卷(+ 1M行),标识速度更快
请参阅此链接,以根据utly4life的评论进行深入分析。
alter sequence increment by ...
简单地为新行腾出空间,然后使用base + row_number()或其他任何实际值来优化批处理插入性能。
最近,对于身份与序列,有一点需要考虑。似乎MSFT现在建议顺序,如果您想保持身份无间隙。我们遇到一个问题,即身份之间存在巨大差距,但是根据此声明,突出显示的内容可以解释我们的问题,即SQL缓存了身份,重新启动后我们丢失了这些数字。
服务器重新启动或其他故障后的连续值–由于性能原因,SQL Server可能会缓存标识值,并且在数据库故障或服务器重新启动期间某些分配的值可能会丢失。这可能导致插入时身份值出现空白。如果差距不可接受,则应用程序应使用自己的机制来生成键值。将序列生成器与NOCACHE选项一起使用可以将间隔限制为从未提交的事务。