SQL Serverテーブルが
そして、更新ステートメント
この更新に必要なピークディスクスペースの消費を減らす(データファイル、ログファイル、tempdb-該当する場合)に必要なテクニックは何ですか?
この質問では、次のことが許可されています。
ほんの数週間前に同様のプロセスを経験しました。数回の試行の後、いくつかの大きなテーブル(そのうちの1つは1億行を超え、80 GB近く)を使用して、処理を高速化し、トランザクションログを小さく保つために、次の手順を思いつきました。
ALTER DATABASE [my_db] SET RECOVERY SIMPLE WITH NO_WAIT( check for more info )
トランザクションの分離レベルを設定して読み取りをコミットしません( 詳細はここをチェックしてください )
非クラスター化インデックスを削除:この手順では、各操作でインデックスを更新する必要があるため、面倒を回避できます( 詳細については、Brent Ozarブログを確認してください )
バッチの使用:mrdennyの提案に従って、必要なことをすべて実行し、更新、削除、挿入を小さなチャンクで行います。
以下は、一度に1000行の更新のバッチ処理のサンプルです。
UPDATE TOP(1000) your_table
SET col1 = new_value
WHERE <your_condition>
WHILE @@rowcount > 0
BEGIN
UPDATE TOP(1000) your_table
SET col1 = new_value
WHERE <your_condition>;
END;
GO
非クラスター化インデックスを復元する
トランザクションアイソレーションレベルの設定READ COMMITTED
ALTER DATABASE [my_db] SET RECOVERY FULL;
基本的に、1つの大規模なトランザクションが発生しないように、更新を1000行または10000行の小さなチャンクにバッチ処理するオプションがあります。 ID列または日付列がある場合、これは簡単に使用できますが、少しトリッキーではありませんが、それでも実行可能です。
すべての行が更新されるまで、トップリミッターで更新を使用し、ステートメントを複数回実行します。
クラスタ化インデックスがない場合(理論的には1つあるため):列で更新する内容に注意してください。レコードサイズを大きくすると、多くの転送されたレコードで終了する可能性があります(dm_db_index_physical_stats-forwarded_record_countを参照)。
ただし、クラスター化インデックスでは、更新された行サイズに注意する必要があります。ページの分割や断片化につながる可能性があります。定期的なメンテナンスがある場合、トランザクションログのサイズが大きくなる可能性があります。
可能であれば、復旧モデルを単純に変更します。変更するレコードの総数に関係なく、トランザクションログとして必要なのはバッチチャンクサイズのみです。ジョブ全体を再開できることを確認してください。最初からすべての行ではなく、変更されていない行のみが更新されます。
この列にインデックスがあった場合は、更新のためにそれを無効にし、後でそれを再構築する必要があります。
これらの列の統計情報を確認することもできますが、これはパフォーマンスに関する質問なので、質問していません。