0

我有一个清理过程,每天需要删除表中大约 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 数据库模式,在这种情况下日志不应该不会增长吗?还是删除存储过程如此“快”,以至于我没有给实际删除行的过程提供保持日志清洁所需的时间?

4

2 回答 2

1

根据您的情况,您可以使用分区视图而不是分区表。就像是:

create table A
(
    X int,
    Y int,
    Z varchar(300),
    primary key (X,Y),
    check (X = 1)
)

create table B
(
    X int,
    Y int,
    Z varchar(300),
    primary key (X,Y),
    check (X = 2)
)

create table C
(
    X int,
    Y int,
    Z varchar(300),
    primary key (X,Y),
    check (X = 3)
)

go

create view ABC
as
select * from A
union all
select * from B
union all
select * from C

go

insert abc (x,y,z)
values (1,4,'test')

insert abc (x,y,z)
values (2,99,'test'), (3,123,'test')

insert abc (x,y,z)
values (3,15125,'test')

select * from abc

truncate table c

select * from abc
于 2012-04-11T17:41:15.917 回答
0

如果我正确理解您的问题,您想要的是自动滑动窗口和分区表。

于 2012-04-11T06:36:36.960 回答