在Identity上自动设置新的种子值

时间:2012-03-30 12:28:49

标签: sql sql-server sql-server-2008 tsql sql-server-2008-r2

类似问题:How to automatically reseed after using identity_insert?

我有一个每天运行一次的存储过程,此过程的一部分是从表中删除〜百万行并重新插入相似数量的行(还有数百万个其他行不受影响),一次它完成了它重建表上准备使用的所有索引。

性能方面,我没有问题,唯一的烦恼是主键过大 - 主键是IDENTITY INT - 显然,删除一百万行然后重新插入叶子我每天的差距大约为100万。

因此,我希望在DELETE之前INSERT之后重新设置ID列。

我知道我可以使用CHECKIDENT来重新设置标识列 - 但前提是在调用CHECKIDENT之前知道新的种子值 - 即在{MAX()之前使用CHECKIDENT 1}}。

我的表是一个非常高的流量表,虽然它不太可能,在此过程中可能尝试其他插入/删除的可能性很小,因此我有点担心使用MAX()+ 1来确定我的新的种子值(即在执行MAX()之后但在完成CHECKIDENT之前从其他地方插入的行 - 这将导致错误),例如:

DECLARE @NewSeed INT 
SELECT  @NewSeed = ISNULL(MAX(IdentityColumn), 0)
FROM    tbl_Whatever 
DBCC CHECKIDENT('tbl_Whatever', RESEED, @NewSeed) 

我的问题:根据Identity列的当前最大值,是否有更灵活的方法来执行重新设定? - 我假设答案是否定的,但我想我会问。

SQL版本是2008 R2

2 个答案:

答案 0 :(得分:1)

使用事务更新种子。此操作非常快,您无需担心锁定。

答案 1 :(得分:0)

正如Dems所说,将身份设置为Max + 1并不能消除差距 这更复杂,但确实填补了空白。

  1. 删除
  2. 重置身份(在交易中)
  3. 确定是否存在空白
  4. 如果有间隙,则在SET IDENTITY_INSERT ON的情况下插入行并填写空白
  5. 显然,存储过程需要确定下一个间隙值。

    如果要插入的数量与删除的数量相同,则甚至无需重置身份。

    我认为您甚至可以使用其他插件,并且他们将使用自动标识

    来自文档http://msdn.microsoft.com/en-us/library/ms188059.aspx

    任何时候,会话中只有一个表可以将IDENTITY_INSERT属性设置为ON。如果某个表已将此属性设置为ON,并且为另一个表发出了SET IDENTITY_INSERT ON语句,则SQL Server将返回一条错误消息,指出SET IDENTITY_INSERT已经为ON并报告其设置为ON的表。

    如果插入的值大于表的当前标识值,SQL Server会自动使用新插入的值作为当前标识值。