アプリケーションからのイベントを記録するロギングテーブルがありますが、古いエントリを削除しようとすると、サーバーの速度が低下し、アプリケーションのデータベース使用が保留されます。新しいログイベントの作成を中断せずに、または他のデータベース操作を禁止することなく、30日以上経過したログエントリをすばやく削除することができます。ロギングテーブルのパフォーマンスを削除
INFO:
ロギングテーブルはとても一般的には、ロギングの月の約10万行を持って よ30万行の日を挿入します。
私はかなり弱い機械、4GBのRAM
IDフィールド上のPKインデックスが、無い他のインデックスや外国 キーがあります上のSQL Expressサーバーを使用しています。
このテーブルは、ログ以外には使用されないため、他の操作は実行されません。
テーブルスキーマ:
CREATE TABLE [dbo].[LogEvents](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[Occurred] [datetime] NOT NULL,
[Message] [nvarchar](max) NOT NULL,
[Severity] [nchar](10) NOT NULL,
[Source] [nvarchar](50) NOT NULL,
[LotNo] [nchar](10) NULL,
[Code] [int] NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
現在、私はバッチで古いログをクリアするには毎分以下のストアドプロシージャを呼び出すアプリケーションを持っています。
CREATE PROCEDURE [dbo].[ClearLogsOlderThan]
@Days int
AS
DELETE TOP (4500) from LogEvents
WHERE DATEDIFF(dy, [Occurred], GETDATE()) > @Days
私の質問(@Days = 30をしてみましょう):
古い行を削除するためのより良い方法はありますか?
実行計画では、PKインデックスが使用されていることが示されていますが、これは実際に比較しているため、日時カラムのインデックスが良いでしょうか?
古い行を削除して新しいレコードを挿入すると、インデックスの有効性が損なわれますか?それは頻繁な再構築が必要でしょうか?新しい行は常に順次になり、古い行だけが削除されます。
次のクエリは、理論的には高速に動作しますか?実行計画を比較すれば、それは可能だが、私は第二の意見が欲しい。 PK列のようなBIGINTの代わりに@oldIDを宣言するとパフォーマンスが低下しますか?
QUERY:
DECLARE @oldID as int;
SET @oldID = (SELECT TOP 1 [Id]
FROM [LogEvents]
WHERE DATEDIFF(DY, [Occurred], GETDATE()) > 30
ORDER BY [Id] DESC)
DELETE TOP (4500) FROM LogEvents
WHERE [Id] <= @oldID
毎分ログテーブルをクリーニングする必要がありますか?またはサーバーに空き容量がある夜間に行うことができますか? – LONG
@LONGこれは、データをロギングするマシンは、潜在的に24時間365日実行する可能性のある行にあります。私は実際にそれが必要でない限り、ロギングをクリアする必要があるため、何らかの操作制限を引き起こしたくありません。 – EMUEVIL