【发布时间】:2012-04-14 03:17:18
【问题描述】:
类似问题:How to automatically reseed after using identity_insert?
我有一个每天运行一次的存储过程,该过程的一部分是从表中删除约百万行并重新插入相似数量的行(还有数百万其他行不受影响),一次它完成它重建表上的所有索引以供使用。
性能方面,我没有问题,唯一的烦恼是主键的大小过大 - 主键是IDENTITY INT - 显然,删除一百万行然后重新插入给我留下了〜每天1000000个缺口。
所以,我想在DELETE 之后的INSERT 之前重新设置 ID 列。
我知道我可以使用 CHECKIDENT 重新设定标识列的种子 - 但前提是在调用 CHECKIDENT 之前知道新的种子值 - 即在 CHECKIDENT 之前立即使用 MAX()。
我的表是一个非常高流量的表,虽然不太可能,但在此过程中可能会尝试其他插入/删除的可能性很小,因此我有点担心诉诸 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
【问题讨论】:
-
只使用 BIGINT?如果超过 20 亿个正值还不够,BIGINT 会产生超过 90 亿个正值。
-
如果我避免了差距,INT 就足够大了。切换到 BIGINT 将只是每行增加 4 个字节毫无意义(考虑到 5+ 百万行,这是很多浪费的字节(20MB?)) - 而且,它是实用性方面 - 例如,在接口/html表/报告上,我们不想要这些庞大的数字和令人困惑的差距
-
这有点跑题了 - 抱歉 - 当你说不是所有的记录都被删除时,你是否保证未触及的记录没有高 id 值?如果您只留下一条记录,并且该记录具有最高的 id,那么您在这里没有任何好处。 [回到主题;我认为你只有这样做的唯一方法。]
-
嗨,Dems,一个有效的问题。但是是的,我敢肯定,有问题的表格是基于日期的(未来 2 年以上的预订基于其他地方的元信息),根据日期删除行并重新插入更新版本。只有行 getdate() + 1 day 被删除,所有行
-
为什么要加载这么多要删除的记录?为什么不让您的加载过程只选择您想要保留或加载到临时表的记录,然后在那里进行处理,然后发送到 prod 表?
标签: sql sql-server sql-server-2008 tsql sql-server-2008-r2