SQL Server 2012以降のパフォーマンスの向上により、この動作が発生しています。
IDENTITY
を割り当てるときに、デフォルトで1,000のキャッシュサイズを使用するようになりました。 int
の値 列を開いてサービスを再起動すると、未使用の値が「失われる」可能性があります(bigint
のキャッシュサイズは10,000です /numeric
)。
これはドキュメントに記載されています
SQL Serverは、パフォーマンス上の理由でID値をキャッシュする場合があり、割り当てられた値の一部は、データベースの障害またはサーバーの再起動中に失われる可能性があります。これにより、挿入時にID値にギャップが生じる可能性があります。ギャップが許容できない場合、アプリケーションは独自のメカニズムを使用してキー値を生成する必要があります。
NOCACHE
でシーケンスジェネレータを使用する オプションを使用すると、コミットされないトランザクションへのギャップを制限できます。
表示したデータから、これは12月22日のデータ入力後に発生し、SQLServerを再起動したときに値1206306 - 1207305
が予約されたように見えます。 。 12月24〜25日のデータ入力が行われた後、別の再起動が行われ、SQLServerは次の範囲1207306 - 1208305
を予約しました 28日のエントリに表示されます。
異常な頻度でサービスを再起動しない限り、「失われた」値によってデータ型で許可されている値の範囲に大きな凹みが生じる可能性は低いため、最善のポリシーはそれについて心配することではありません。
これが何らかの理由であなたにとって本当の問題である場合、いくつかの可能な回避策は...
-
SEQUENCE
を使用できます ID列の代わりに、たとえば小さいキャッシュサイズを定義し、NEXT VALUE FOR
を使用します 列のデフォルト。 - または、
IDENTITY
を作成するトレースフラグ272を適用します 2008R2までのバージョンで記録された割り当て。これは、すべてのデータベースにグローバルに適用されます。 - または、最近のバージョンの場合は、
ALTER DATABASE SCOPED CONFIGURATION SET IDENTITY_CACHE = OFF
を実行します。 特定のデータベースのIDキャッシュを無効にします。
これらの回避策のいずれもギャップがないことを保証するものではないことに注意する必要があります。これは、IDENTITY
によって保証されたことはありません。 インサートをテーブルにシリアル化することによってのみ可能になるためです。ギャップのない列が必要な場合は、IDENTITY
とは異なるソリューションを使用する必要があります。 またはSEQUENCE