バッチ削除の提案を拡張するには、これをはるかに定期的に(おそらく20秒ごとに)行うことをお勧めします-バッチ削除は簡単です:
WHILE 1 = 1
BEGIN
DELETE TOP ( 4000 )
FROM YOURTABLE
WHERE YourIndexedDateColumn < DATEADD(MINUTE, -20, GETDATE())
IF @@ROWCOUNT = 0
BREAK
END
ロックが解除されるのを待つ間、挿入はわずかに遅れる場合がありますが、エラーではなく挿入する必要があります。
ただし、テーブルに関しては、非常に高速なRAID 10アレイ(おそらくパーティション化されている場合もあります)で見られると予想されるトラフィックがこれだけ多いテーブルは、ディスクに対応していますか?トランザクションログはデータファイルとは異なるディスクにありますか?- 彼らはする必要があります
編集1-あなたのコメントへの応答
データベースをSIMPLEリカバリにするには:
ALTER DATABASE Database Name SET RECOVERY='SIMPLE'
これにより、基本的に、特定のデータベースでのトランザクションログがオフになります。つまり、データが失われた場合は、最後の完全バックアップ以降のすべてのデータを失う必要があります。それでよければ、大規模なトランザクションを実行するときに多くの時間を節約できるはずです。(トランザクションが実行されている間、ロギングは引き続きSIMPLEで行われることに注意してください-トランザクションのロールバックを有効にします)。
データベース内にデータを失う余裕がないテーブルがある場合は、データベースを完全リカバリモードのままにする必要があります(つまり、トランザクションはログに記録されます(サーバーのメンテナンスプランによって* .trnファイルにフラッシュされることが望ましい)。私の質問で述べたように、2つのデータベース(1つはFULL、もう1つはSIMPLE)があることを妨げるものは何もありません。FULLデータベースは、データを失う余裕がないフォアテーブルになります(つまり、トランザクションログを適用してデータを復元することができます)特定の時間)およびSIMPLEデータベースは、障害が発生した場合にデータの損失を許容できるこれらの大規模なトラフィックの多いテーブル用です。
これはすべて、毎晩完全な(* .bak)ファイルを作成し、30分ごとにログファイルを* .trnファイルにフラッシュすることを前提としています)。
インデックスの質問に関しては、実行プランを確認して「テーブルスキャン」が表示された場合、日付列にインデックスを付けることが不可欠です。これは、インデックスが欠落していることを示します。
私が推測するあなたの日付列は、DEFAULTをgetdate()に設定する制約のあるDATETIMEですか?
これをBIGINTYYYYMMDDHHMMSSに置き換えてから、その列にCLUSTEREDインデックスを適用すると、パフォーマンスが向上する場合があります。ただし、テーブルごとに1つのクラスター化インデックスしか持てないことに注意してください。非クラスター化インデックスを使用します。(知らなかった場合、クラスター化インデックスは基本的にSQLに情報をこの順序で格納するように指示します。つまり、20分を超える行を削除すると、SQLはページ間を移動するのではなく、文字通り順番に情報を削除できます。