【发布时间】:2016-08-11 15:10:13
【问题描述】:
SQL Server 2008 R2 企业版
我有一个包含 3 个表的数据库,我将其保留时间为 15 天。这是一个非常活跃的日志数据库,大小约为 500 GB,除非被清除,否则每天消耗约 30 GB。我似乎无法赶上其中一张桌子,我落后了。该表有 2.2 亿行,每晚需要清除大约 10-12 百万行。我目前需要清除 3000 万行。由于竞争表锁的传入插入量,我只能在晚上运行此清除。我已确认所有内容均已正确编入索引,并已运行 Brent Ozars sp_Blitz_Index 以确认这一点。有什么方法可以优化我在下面做的事情吗?我为每个表运行相同的清除步骤。
- 删除并创建 3 个清除表:Purge_Log、Purge_SLogHeader 和 Purge_SLogMessage。
2.在清除表中插入行(每个表需要 5 分钟):
Insert Into Purge_Log
Select ID from ServiceLog
where startTime < dateadd (day, -15, getdate() )
--********************************************* *******
Insert into Purge_SLogMessage
select serviceLogId from ServiceLogMessage
where serviceLogId in ( select id from
ServiceLog
where startTime < dateadd (day, -15, getdate() ))
--********************************************* *******
Insert into Purge_SLogHeader
Select serviceLogId from ServiceLogHeader
where serviceLogId in ( select id from
ServiceLog
where startTime < dateadd (day, -15, getdate() ))
插入之后,我运行以下每个表的差异:
SET ROWCOUNT 1000
delete_more:
delete from ServiceLog
where Id in ( select Id from Purge_Log)
IF @@ROWCOUNT > 0 GOTO delete_more
SET ROWCOUNT 0
基本上有没有人看到我可以让这个过程运行得更快或者有不同的方法来完成它。我使查询尽可能简单,并且只有一个子查询。我使用了一个连接,执行查询计划说以这种方式完成它的时间是相同的。任何指导将不胜感激。
【问题讨论】:
-
首先你应该停止像这样使用 ROWCOUNT。不推荐将其用于这样的删除。 msdn.microsoft.com/en-us/library/ms188774.aspx 您应该改为使用循环来进行批量删除。作为一种可行的编码实践,应该从你的想法中删除 GOTO。我不太明白为 Purge_Log 设置一个单独的表。为什么不直接删除开头的行而不是将它们全部复制到另一个表中?
-
感谢您查看此内容。我将查看循环中的删除选项并重新评估 GOTO。我没有在开头删除行,因为在删除中包含 where 子句需要更多时间来搜索 2.2 亿行以查找日期。我将这些预取到新表中,然后对它们运行删除以提高删除速度。
-
您也可以考虑分区,因为您使用的是企业版..查看此链接..mssqltips.com/sqlservertip/2780/…
标签: sql-server tsql sql-server-2012 sql-server-2008-r2