10

SQL Server 2012 SP1 x64 (11.0.3000.0) を実行しています

InvoiceId自動インクリメントの主キーとしてフィールドを含む次のテーブルがあります。

CREATE TABLE Orders(
    InvoiceId           bigint           IDENTITY(1001,1) NOT FOR REPLICATION,
    OrderId             varchar(8)       NOT NULL,
    ...  -- other fields removed for brevity
    CONSTRAINT [PK_ORDERS] PRIMARY KEY CLUSTERED (InvoiceId)
    ON [PRIMARY], 
)

次のような単純なストアド プロシージャを使用して、新しい行が挿入されます。

SET  XACT_ABORT ON
SET  NOCOUNT ON

BEGIN TRANSACTION
    INSERT INTO Orders(
          OrderId,
          ... -- other fields removed for brevity
        )
    VALUES  (
          @orderId,
          ...
        )              

    SELECT @newRowId = SCOPE_IDENTITY()
COMMIT TRANSACTION

上記の sproc は、新しく作成された行 ID ( Orders.InvoiceId) を呼び出し元に返します。

コードは[InvoiceId]1001 から始まり、連続する挿入ごとに 1 ずつ増加して、完全に機能していました。

ユーザーは約 130 行を挿入しました。[InvoiceId]は 1130 でしたが、次の挿入でその値は11091に跳ね上がりました!

データのスクリーンショットは次のとおりです。

データ

ここで何が起こったのか、私は困惑しています。auto-inc カウンターが突然 10,000 ポイント近くスキップしたのはなぜですか?

の値を使用して[InvoiceId]バーコードを生成するため、値が特定の範囲内、できれば連続したシリーズ内にとどまるようにします。

T-SQL のドキュメントを熟読しましたが、問題に関連するものは見つかりませんでした。これは ID フィールドの通常の動作 (任意の母集団) ですか?

4

2 に答える 2

3

更新マーティングとアロンのおかげで、回避策が見つかりました。マイクロソフトの公式回答は次のとおりです。

SQL Server 2012 では、他の機能への投資に対応するために、ID プロパティの実装が変更されました。以前のバージョンの SQL Server では、ID 生成の追跡は、生成された各 ID 値のトランザクション ログ レコードに依存していました。SQL Server 2012 では、ID 値をバッチで生成し、バッチの最大値のみをログに記録します。これにより、トランザクション ログに書き込まれる情報の量と頻度が減り、挿入のスケーラビリティが向上します。

以前のバージョンの SQL Server と同じ ID 生成セマンティクスが必要な場合は、次の 2 つのオプションを利用できます。

• トレース フラグ 272 を使用する o これにより、生成された ID 値ごとにログ レコードが生成されます。このトレース フラグをオンにすると、ID 生成のパフォーマンスが影響を受ける場合があります。

• NO CACHE 設定でシーケンス ジェネレータを使用する ( http://msdn.microsoft.com/en-us/library/ff878091.aspx ) o これにより、生成されたシーケンス値ごとにログ レコードが生成されます。NO CACHE を使用すると、シーケンス値生成のパフォーマンスが影響を受ける可能性があることに注意してください。

例:

CREATE SEQUENCE s1 AS INT START WITH 1 NO CACHE; 
CREATE TABLE t1 (Id INT PRIMARY KEY DEFAULT NEXT VALUE FOR s1, col INT NOT NULL);
于 2013-08-30T05:46:59.760 に答える
0

または、カウンター付きの専用テーブルを用意することもできます。これは良いデザイン パターンではありませんが、ID の動作を完全に制御できます。

于 2013-08-29T16:16:52.327 に答える