在具有聚簇索引的表中,DELETE命令太慢

Ahm*_*eza 12 sql sql-server-2005

我有一个相当大的名为FTPLog的表,有大约3百万条记录我想添加一个删除机制来删除旧日志,但删除命令需要很长时间.我发现聚簇索引删除需要很长时间.

DECLARE @MaxFTPLogId as bigint
SELECT @MaxFTPLogId = Max(FTPLogId) FROM FTPLog WHERE LogTime <= DATEADD(day, -10 , GETDATE())
PRINT @MaxFTPLogId
DELETE FROM FTPLog WHERE FTPLogId <= @MaxFTPLogId
Run Code Online (Sandbox Code Playgroud)

我想知道如何提高删除性能?

And*_*mar 14

它可能很慢,因为大型删除会生成一个大的事务日志.尝试以块的形式删除它,例如:

WHILE 1 = 1
BEGIN
    DELETE TOP (256) FROM FTPLog WHERE FTPLogId <= @MaxFTPLogId
    IF @@ROWCOUNT = 0
        BREAK
END
Run Code Online (Sandbox Code Playgroud)

这会产生较小的交易.它通过为其他进程创建呼吸空间来缓解锁定问题.

您还可以查看分区表.这些可能允许您通过删除整个分区来清除旧条目.


Qua*_*noi 7

由于它是一个日志表,因此无需进行集群化.

你不太可能会搜索它Id.

改变你PRIMARY KEY的想法,使它成为非聚集的.这将使用HEAP更快的存储方法DML:

ALTER TABLE FTPLog DROP CONSTRAINT Primary_Key_Name
ALTER TABLE FTPLog ADD CONSTRAINT Primary_Key_Name PRIMARY KEY NONCLUSTERED (FTPLogId)
Run Code Online (Sandbox Code Playgroud)

,只是发出:

SELECT @MaxFTPLogTime = DATEADD(day, -10 , GETDATE())
PRINT @MaxFTPLogId
DELETE FROM FTPLog WHERE LogTime <= @MaxFTPLogTime
Run Code Online (Sandbox Code Playgroud)