我有一個日誌記錄表,它記錄應用程序中的事件,但在嘗試刪除舊條目時,服務器速度變慢並阻止應用程序使用數據庫。我希望能夠快速刪除超過30天的日誌條目,而不會中斷創建新日誌事件或禁止其他數據庫操作。刪除日誌表上的性能
信息:
的記錄表中插入每天約300,000行所以一般它會 擁有約10萬行一個月的日誌記錄。
我使用了一個相當薄弱的機器,4GB內存
上有一個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)
目前我的應用程序中調用以下存儲過程的每一分鐘來清除舊日誌中的批次。 (讓@days = 30)
CREATE PROCEDURE [dbo].[ClearLogsOlderThan]
@Days int
AS
DELETE TOP (4500) from LogEvents
WHERE DATEDIFF(dy, [Occurred], GETDATE()) > @Days
我的問題:
有沒有更好的方式來刪除舊行?
執行計劃顯示正在使用PK索引,但會在datetime列上的索引更好,因爲這就是我實際上正在比較的內容?
不斷刪除舊行並插入新記錄會破壞索引的有效性嗎?它需要經常重建嗎?新行應始終是順序的,只有舊行纔會被刪除。
下面的查詢理論上會工作得更快嗎?比較執行計劃表明它會,但我希望得到第二個意見。聲明@oldID是一個INT而不是像PK列一樣的BIGINT會有性能下降嗎?
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/7的生產線上。我不想引起任何形式的操作限制,僅僅因爲日誌需要被清除,除非它真的需要它。 – EMUEVIL