少し手に負えなくなったテーブルがあります。私はそれ自体DBAではありませんが、大量の行を一度に削除するとトランザクションログの問題が発生したり、削除中のシステム全体のパフォーマンスが低下したりする可能性があることを思い出しているようです...
他のアクセス/パフォーマンスを過度に妨げてトランザクションログの問題を防ぐために、レコードを小さなバッチで削除するジョブを作成する効率的な方法はありますか?
このプロセスはかなり遅くなる可能性があります
追加のコンテキストでは、削除基準は次のようなものに基づいています... where x like '%blah%'
。また、1つのクラスター化インデックスと5つの非クラスター化インデックスがあります。
あなたはそれをチャンクに分割することができます-ループで削除してください;それぞれが独自のトランザクションである反復を削除し、各ループ反復の終わりにログをクリアします。最適なチャンクサイズを見つけるには、いくつかのテストが必要です。
詳細を説明し、さまざまなシナリオのテストを実行して影響(期間、トランザクションログ)を示すアーロンバートランドによるこの記事をご覧になることをお勧めします。 http://sqlperformance.com/2013/ 03/io-subsystem/chunk-deletes
where x like '%blah%'
削除条件-クエリを作成します検索不可(インデックスを活用してインデックスシークを実行できません)。したがって、列x
をサポートするインデックスがある場合でも、それはスキャンになります。
このためのリソース:
かなりシンプルです。これは、テストを行うためのフレームワークです。
CREATE TABLE #DelTest (ID INT IDENTITY, name NVARCHAR(128));
INSERT INTO #DelTest (name) SELECT name FROM sys.objects;
SELECT COUNT(*) TableNamesContainingSys FROM deltest WHERE name LIKE '%sys%';
go
DECLARE @HowMany INT;
DECLARE @RowsTouched INT;
SET @RowsTouched = 1;
SET @HowMany = 5;
WHILE @RowsTouched > 0
BEGIN
DELETE TOP (@HowMany)
FROM #DelTest
WHERE name LIKE '%sys%';
SET @RowsTouched = @@ROWCOUNT;
END;
SELECT COUNT(*) TableNamesContainingSys FROM #DelTest WHERE name LIKE '%sys%';
DROP TABLE #DelTest;
編集:もちろん、列全体を検索する必要があるため、ワイルドカード検索を開くことは、行を見つけるのに悪名高いです。また、Aaronの投稿で指摘されているように、SIMPLEモードにするか、ログバックアップを実行してログファイルが過度に大きくならないようにすることで、ログも管理する必要があります。