2013-08-20 57 views
2

我有三列的表,和基本的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.在表的設計,PatchHistoryIdint,標識種子爲1,增量爲1

+0

看來,每次重新啓動SQL服務後,SQL都會跳轉到另外一千個:)我已經測試過了。爲什麼這是更好的解決方案,而不是舊的身份認同,有什麼好的理由嗎? – veljasije

+0

從來沒有真正保證身份只會增加1,因爲這些值可以在事務中給出,那麼如果事務要回滾,身份值仍然被使用。 –

+0

好吧,那是特定情況,但我沒有交易,除非你的意思是INSERT語句創建的隱式交易。但是,如果我指定我的種子爲1,並且增量爲1,那麼重新啓動後的sql server可以跳過千位數 – veljasije

回答

5

由於與新的序列功能連接的代碼更改,在SQL 2012標識的分配已更改出於性能的考慮。標識值現在預先分配爲1,000(對於int列)或10,000(對於bigint列)塊。

如果實例停止(如重啓或故障切換),未使用的預分配值將被丟棄(因爲持久「下一個」指針已被設置爲下一個塊)。

此外,連續的身份值一直通過中止事務丟失,但由於每天有1,000個塊,所以我會假設每天都會重新啓動實例(原因是您不應該這樣做if你沒有真正的好理由)。

Source link, see Michael Duhons entry

1

由於已經由以前的答案解釋,這是由於的方式,SQL Server 2012的緩存標識值然後在服務器重新啓動過程中丟失。

如果這導致了您的問題,您可以通過使用序列而不是標識列並指定NO CACHE子句來解決此問題,然後您的列的默認值爲NEXT VALUE FOR sequence_name。請注意,雖然這將有助於身份值的跳躍,但它會稍微影響性能,但如果您在該示例中給出的表格代表您實際執行的插入次數,則不應該「這是一個很大的問題。