如何在没有事务的情况下执行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