To zachowanie jest spowodowane poprawą wydajności od czasu SQL Server 2012.
Teraz domyślnie używa rozmiaru pamięci podręcznej 1000 podczas przydzielania IDENTITY
wartości dla int
kolumna i ponowne uruchomienie usługi może "stracić" nieużywane wartości (rozmiar pamięci podręcznej wynosi 10 000 dla bigint
/numeric
).
Jest to wspomniane w dokumentacji
SQL Server może buforować wartości tożsamości ze względu na wydajność, a niektóre z przypisanych wartości mogą zostać utracone podczas awarii bazy danych lub ponownego uruchomienia serwera. Może to spowodować luki w wartości tożsamości podczas wstawiania. Jeśli luki są niedopuszczalne, aplikacja powinna użyć własnego mechanizmu do generowania wartości kluczy. Używanie generatora sekwencji z NOCACHE
opcja może ograniczyć luki do transakcji, które nigdy nie są realizowane.
Z danych, które pokazałeś, wygląda na to, że stało się to po wprowadzeniu danych z 22 grudnia, a po ponownym uruchomieniu SQL Server zarezerwował wartości 1206306 - 1207305
. Po wprowadzeniu danych w dniach 24-25 grudnia wykonano kolejny restart i SQL Server zarezerwował następny zakres 1207306 - 1208305
widoczne we wpisach na 28.
O ile nie uruchamiasz usługi z niezwykłą częstotliwością, wszelkie „utracone” wartości prawdopodobnie nie spowodują znaczącego wgniecenia zakresu wartości dozwolonych przez typ danych, więc najlepszą zasadą jest nie przejmowanie się tym.
Jeśli z jakiegoś powodu jest to dla Ciebie prawdziwy problem, możliwe obejścia to...
- Możesz użyć
SEQUENCE
zamiast kolumny tożsamości i zdefiniuj na przykład mniejszy rozmiar pamięci podręcznej i użyjNEXT VALUE FOR
w domyślnej kolumnie. - Lub zastosuj flagę śledzenia 272, która powoduje, że
IDENTITY
przydział logowany jak w wersjach do 2008 R2. Dotyczy to globalnie wszystkich baz danych. - Lub, w przypadku ostatnich wersji, wykonaj
ALTER DATABASE SCOPED CONFIGURATION SET IDENTITY_CACHE = OFF
aby wyłączyć buforowanie tożsamości dla określonej bazy danych.
Powinieneś mieć świadomość, że żadne z tych obejść nie zapewnia żadnych luk. Nigdy nie było to gwarantowane przez IDENTITY
ponieważ byłoby to możliwe tylko przy serializacji wstawek do tabeli. Jeśli potrzebujesz kolumny bez przerw, musisz użyć innego rozwiązania niż IDENTITY
lub SEQUENCE