我有一个清理过程,需要每天删除表中大约800万行(有时更多)。此过程使用C#编写,并使用SMO查询表索引的模式,在执行以500K行批量删除的sproc之前禁用它们。
我的问题是整个操作都在一个事务中。 sproc在TransactionScope内部执行,该事务处理器使用TransactionScopeOption.Suppress进行配置(这与其他每个启动一个新的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数据库模式,在这种情况下,日志不应该增长吗?或者删除sproc是如此“快”,我没有给出实际删除行的进程,以保持日志清理所需的时间?
答案 0 :(得分: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
答案 1 :(得分:0)
如果我正确理解您的问题,您需要的是automatic sliding window和分区表。