2017-09-19 3 views
1

アプリケーションからのイベントを記録するロギングテーブルがありますが、古いエントリを削除しようとすると、サーバーの速度が低下し、アプリケーションのデータベース使用が保留されます。新しいログイベントの作成を中断せずに、または他のデータベース操作を禁止することなく、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をしてみましょう):

  1. 古い行を削除するためのより良い方法はありますか?

  2. 実行計画では、PKインデックスが使用されていることが示されていますが、これは実際に比較しているため、日時カラムのインデックスが良いでしょうか?

  3. 古い行を削除して新しいレコードを挿入すると、インデックスの有効性が損なわれますか?それは頻繁な再構築が必要でしょうか?新しい行は常に順次になり、古い行だけが削除されます。

  4. 次のクエリは、理論的には高速に動作しますか?実行計画を比較すれば、それは可能だが、私は第二の意見が欲しい。 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 
+1

毎分ログテーブルをクリーニングする必要がありますか?またはサーバーに空き容量がある夜間に行うことができますか? – LONG

+0

@LONGこれは、データをロギングするマシンは、潜在的に24時間365日実行する可能性のある行にあります。私は実際にそれが必要でない限り、ロギングをクリアする必要があるため、何らかの操作制限を引き起こしたくありません。 – EMUEVIL

答えて

3

ログをクリアするには、これは頻繁にあなたのクエリにすることによって何のために存在しないとして、あなたが4500行を指定していない、特に以来、少し行き過ぎです。しかし、最大の問題は、関数内にカラムがあるため、クエリが非SAARableであることです。代わりにgetdateでdatemathを実行し、少なくとも問合せでOccurred列の索引を使用できます。

ABS()* -1を使用して既存のコードが正しく動作するようにしました。

where Occurred < dateadd(day, abs(@Days) * -1, getdate()) 
+0

ありがとう!だから私は[Occurred]列にインデックスを作成し、関数の外で発生した列を分離するためにクエリを調整する必要がありますか? 古い行が最初に削除されても構いませんので、私はorder byを含めませんでした。注文を強制するとスピードが上がりますか? – EMUEVIL

+0

何かあれば、遅くなるでしょう。どのようなものが削除されても気にしない場合、4500というような奇数はなぜですか? –

+0

私は、5000行以上の行を一度に削除すると、テーブル全体が強制的にロックされることをどこかで読んでいます。だから...迷信? https://technet.microsoft.com/en-us/library/ms184286(v=sql.105).aspx 発生列にインデックスを追加する必要がありますか? – EMUEVIL

関連する問題