1

バージョンごとに1,500万行になるいくつかのデータの「バージョン管理」テーブルがあります。構造は次のとおりです。

[ID] bigint,
[version] int,
[somecolumn] int,
[anothercolumn] int,
[thirdcolumn] tinyint

そして、次のクエリのように、あるバージョンを別のバージョンに常にコピーする必要があります。

INSERT INTO myTable 
    (SELECT ID, version + 1, somecolumn, anothercolumn, thirdcolumn 
     FROM myTable 
     WHERE version = @version)

しかし、問題は、1 回の操作で 10 秒以上かかるなど、実行速度が非常に遅いことです。この操作を電光石火のように速くするにはどうすればよいでしょうか? 私はすでに一時テーブルを選択してそこからマージしようとしましたが、それ以上は速くなりませんでした..

4

3 に答える 3

1

いくつかの考え:

  1. 一時テーブルを使用しても役立つ可能性はほとんどありません。それは魔法でしょう。
  2. NOLOCKを使用しても役立つ可能性はほとんどありません。同時トランザクションが1つしかないため(少なくともテストシステムでは)、これがブロッキングの問題であるという証拠はわかりません。
  3. インデックスの再構築が維持よりも速い理由がわかりません。あなたのテーブルにはおそらくバージョンがほとんどありませんか?多くを取得すると、インデックスの再構築がますます遅くなります。長期的な解決策ではありません。
  4. 挿入がシーケンシャルになるように、クラスター化インデックスキーを(バージョン、ID)に変更してみてください。ランダムDMLは、シーケンシャルDMLよりもはるかに低速です。
于 2012-08-14T09:20:48.487 に答える
0

これが機能するかどうかを確認してください。

begin
  SELECT ID, version + 1, somecolumn, anothercolumn, thirdcolumn 
  into #temp
  FROM myTable 
  WHERE version = @version

  ALTER INDEX IDX_tableName_VERSION ON tableName.version DISABLE 

  INSERT INTO myTable
  select * from #temp

  ALTER INDEX IDX_tableName_VERSION ON tableName.version ENABLE 

end
于 2012-08-14T08:18:18.570 に答える
0

バージョン列にインデックスを追加しましたか? それは物事をスピードアップするはずです。

CREATE INDEX IDX_tableName_VERSION ON tableName (version)

アップデート

読み込んだテーブルで NOLOCK を使用するのはどうですか? テーブルに対する他のトランザクションからシステムでダーティ リードを取得できると思われる場合は無効です。私は以前にこれを使用していくつかの成功を収めましたが、注意して使用する必要があります!

INSERT INTO myTable 
    (SELECT ID, version + 1, somecolumn, anothercolumn, thirdcolumn 
     FROM myTable WITH(NOLOCK)
     WHERE version = @version)
于 2012-08-14T07:37:34.283 に答える