我有一个包含三列的表,基本的SELECT语句如下所示:
SELECT TOP 1000 [PatchHistoryId]
,CASE
WHEN [PatchName] LIKE N'1_%' THEN '1_aaa'
WHEN [PatchName] LIKE N'2_%' THEN '2_bbb'
WHEN [PatchName] LIKE N'3_%' THEN '3_ccc'
WHEN [PatchName] LIKE N'4_%' THEN '4_ddd'
WHEN [PatchName] LIKE N'5_%' THEN '5_eee'
WHEN [PatchName] LIKE N'6_%' THEN '6_fff'
WHEN [PatchName] LIKE N'7_%' THEN '7_ggg'
WHEN [PatchName] LIKE N'8_%' THEN '8_hhh' END AS PatchName
,[CreatedDate]
FROM [PatchHistory]
结果如下所示:
PatchHistoryId | PatchName | CreatedDate
-------------------------------------------
1 1_aaa 2013-07-19 12:50:14.637
2 2_bbb 2013-07-19 12:50:16.570
1002 3_ccc 2013-07-26 08:53:33.557
1003 3_ccc 2013-07-26 08:55:38.600
2002 4_ddd 2013-07-29 11:32:28.320
2003 4_ddd 2013-07-29 11:35:02.123
2004 4_ddd 2013-07-29 14:24:36.297
3002 4_ddd 2013-08-01 09:24:01.537
4002 6_fff 2013-08-06 11:18:29.990
5002 7_ggg 2013-08-08 15:22:56.990
6002 8_hhh 2013-08-20 15:15:35.157
6003 8_hhh 2013-08-20 15:16:40.300
6004 8_hhh 2013-08-20 15:18:00.177
6005 8_hhh 2013-08-20 15:18:00.370
6006 8_hhh 2013-08-20 15:18:00.587
6007 8_hhh 2013-08-20 15:18:00.747
6008 8_hhh 2013-08-20 15:18:00.957
6009 8_hhh 2013-08-20 15:18:01.100
6010 8_hhh 2013-08-20 15:18:01.263
6011 6_fff 2013-08-20 15:18:17.300
6012 8_hhh 2013-08-20 15:28:30.373
现在,首先我发现身份值非常高,因为我知道我的插入值只有20-30次,而没有删除行。假设这个,最大身份值需要< 100,但不是。
我注意到1000-1003范围内的身份属于一个日期,2000-2004属于另一个日期,6000-6012也属于另一个日期,对我来说这是如此奇怪。
似乎如果我插入数据tomorow,下一个身份将不是6013,而是7000或更大的东西。
在这种情况下可以采取什么措施。
P.S。在表格设计中,PatchHistoryId
为int
,身份种子为1,增量为1。
答案 0 :(得分:5)
由于代码更改与新序列功能相关联,因此出于性能原因,SQL 2012中的身份分配已更改。现在,标识值预先分配为1,000个块(对于int列)或10,000个(对于bigint列)。
如果实例已停止(如重启或故障转移),则会丢弃未使用的预分配值(因为持久的“下一个”指针已设置为下一个块)。
此外,连续的身份值一直都是通过中止的事务丢失的,但是因为你有好的,每天1000块,我会假设每天重启你的实例作为原因(你不应该这样做,如果你没有真正的理由)。
答案 1 :(得分:1)
正如之前的回答所解释的那样,这是由于SQL Server 2012缓存身份值的方式,然后在重新启动服务器时丢失这些身份值。
如果这导致您出现问题,您可以通过使用序列而不是标识列并指定NO CACHE子句来解决此问题,然后使用默认值为NEXT VALUE FOR sequence_name的列。
请记住虽然这会有助于标识值的跳转,但它会稍微影响性能,但如果您在示例中给出的表格代表您实际执行的插入数量,则不应该很大的问题。