U ondervindt dit gedrag vanwege een prestatieverbetering sinds SQL Server 2012.
Het gebruikt nu standaard een cachegrootte van 1.000 bij het toewijzen van IDENTITY
waarden voor een int
kolom en het herstarten van de service kan ongebruikte waarden "verliezen" (de cachegrootte is 10.000 voor bigint
/numeric
).
Dit staat vermeld in de documentatie
SQL Server kan identiteitswaarden cachen om prestatieredenen en sommige van de toegewezen waarden kunnen verloren gaan tijdens een databasefout of het opnieuw opstarten van de server. Dit kan resulteren in hiaten in de identiteitswaarde bij het invoegen. Als hiaten niet acceptabel zijn, moet de toepassing zijn eigen mechanisme gebruiken om sleutelwaarden te genereren. Een sequentiegenerator gebruiken met de NOCACHE
optie kan de hiaten beperken tot transacties die nooit zijn vastgelegd.
Uit de gegevens die u hebt laten zien, lijkt het erop dat dit gebeurde na de gegevensinvoer voor 22 december en toen het opnieuw werd opgestart, heeft SQL Server de waarden gereserveerd 1206306 - 1207305
. Nadat de gegevens voor 24 - 25 december waren ingevoerd, werd opnieuw opgestart en heeft SQL Server het volgende bereik gereserveerd 1207306 - 1208305
zichtbaar in de inzendingen voor de 28e.
Tenzij u de service met ongebruikelijke frequentie opnieuw start, is het onwaarschijnlijk dat "verloren" waarden een significante deuk zullen veroorzaken in het waardenbereik dat door het gegevenstype is toegestaan, dus het beste beleid is om u er geen zorgen over te maken.
Als dit om de een of andere reden een echt probleem voor je is, zijn enkele mogelijke oplossingen...
- U kunt een
SEQUENCE
. gebruiken in plaats van een identiteitskolom en definieer bijvoorbeeld een kleinere cachegrootte en gebruikNEXT VALUE FOR
in een kolom standaard. - Of pas traceringsvlag 272 toe die de
IDENTITY
. maakt toewijzing gelogd zoals in versies tot 2008 R2. Dit geldt globaal voor alle databases. - Of, voor recente versies, voer
ALTER DATABASE SCOPED CONFIGURATION SET IDENTITY_CACHE = OFF
uit om de identiteitscaching voor een specifieke database uit te schakelen.
U moet zich ervan bewust zijn dat geen van deze tijdelijke oplossingen ervoor zorgt dat er geen hiaten zijn. Dit is nooit gegarandeerd door IDENTITY
omdat het alleen mogelijk zou zijn door inserts aan de tafel te serialiseren. Als u een kolom zonder tussenruimte nodig heeft, moet u een andere oplossing gebruiken dan IDENTITY
of SEQUENCE