如何在没有事务的情况下执行sproc?

我有一个清理过程,每天需要删除表中约800万行(有时更多)。 此进程使用C#编写,并使用SMO查询表索引的模式,在执行批量删除500K行之前的sproc之前禁用它们。

我的问题是,整个操作都在交易中。 在一个TransactionScope中执行该sproc,该transactionScope配置了TransactionScopeOption.Suppress(这个运行沿着其他事物启动一个新的TransactionScope),我认为这不会允许一个Transaction,并且在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数据库模式,在这种情况下日志不应该增长吗? 或者是删除存储过程如此“快速”,以至于我没有给出实际删除行所需的时间以保持日志清洁的过程?


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

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

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

链接地址: http://www.djcxy.com/p/62243.html

上一篇: How can a make a sproc execute without a transaction?

下一篇: Sproc performance degrades over time