我有一个清理过程,每天需要删除表中大约 800 万行(有时更多)。此过程是用 C# 编写的,并使用 SMO 查询表索引的架构,在执行批量删除 500K 行的存储过程之前禁用它们。
我的问题是整个操作都存在于事务中。sproc 在配置了 TransactionScopeOption.Suppress 的 TransactionScope 内执行(这与其他事物一起运行,每个都启动一个新的 TransactionScope),我认为这不允许事务,并且在 sproc 中有明确的提交点。
该过程的 C# 部分可以总结为:
try {
DisableIndexes(table);
CleanTable(table);
}
finally {
RebuildIndexes(table);
}
sproc 内部有一个循环,基本上是:
DECLARE @rowCount bigint = 1
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
WHILE @rowCount <> 0 BEGIN
DELETE TOP (@rowsPerBatch) Table
WHERE
ID <= @maxID
SET @rowCount = @@rowcount
END
昨晚这个过程在开始半小时后超时,回滚半小时,索引重建又半小时......零工作的停机时间太长......=(
更新:我已经在一个小样本数据库上运行了这个过程(并且有一个小的超时),这并不像我想的那样。显然,该过程正在正确删除行并按照我的意愿取得进展。尽管如此,日志仍在消耗。由于我处于 SIMPLE 数据库模式,在这种情况下日志不应该不会增长吗?还是删除存储过程如此“快”,以至于我没有给实际删除行的过程提供保持日志清洁所需的时间?