sql >> データベース >  >> RDS >> Sqlserver

SQLServerデータベースでIDの増分が急増しています

    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日のエントリに表示されます。

    異常な頻度でサービスを再起動しない限り、「失われた」値によってデータ型で許可されている値の範囲に大きな凹みが生じる可能性は低いため、最善のポリシーはそれについて心配することではありません。

    これが何らかの理由であなたにとって本当の問題である場合、いくつかの可能な回避策は...

    1. SEQUENCEを使用できます ID列の代わりに、たとえば小さいキャッシュサイズを定義し、NEXT VALUE FORを使用します 列のデフォルト。
    2. または、IDENTITYを作成するトレースフラグ272を適用します 2008R2までのバージョンで記録された割り当て。これは、すべてのデータベースにグローバルに適用されます。
    3. または、最近のバージョンの場合は、ALTER DATABASE SCOPED CONFIGURATION SET IDENTITY_CACHE = OFFを実行します。 特定のデータベースのIDキャッシュを無効にします。

    これらの回避策のいずれもギャップがないことを保証するものではないことに注意する必要があります。これは、IDENTITYによって保証されたことはありません。 インサートをテーブルにシリアル化することによってのみ可能になるためです。ギャップのない列が必要な場合は、IDENTITYとは異なるソリューションを使用する必要があります。 またはSEQUENCE



    1. SQLiteの英数字を含む行を返す

    2. OracleXDBでの制御文字のエスケープ

    3. OracleのNUMTODSINTERVAL()関数

    4. PostgreSQLでのPOSITION()のしくみ