在过去的几天里,我一直在尝试编写一个自动过程的查询,该过程将在指定的日期范围(一个月)内将日志表中的记录删除到另一个表中,然后可以将它们转储到磁盘和记录从数据库中删除。第一种,天真的方法,ala
DELETE FROM <sometable>
OUTPUT DELETED.* INTO [<sometable>_{year}_{month}]
WHERE DATEPART(YEAR, [DateTime]) = {year} AND DATEPART(MONTH, [DateTime]) = {month}
Run Code Online (Sandbox Code Playgroud)
当然炸毁了交易日志。然后我尝试做同样的事情,但现在批量为 1m 行,如下所示
WHILE @@ROWCOUNT > 0
BEGIN
DELETE TOP (1000000) FROM <sometable>
OUTPUT DELETED.* INTO [<sometable>_{year}_{month}]
WHERE DATEPART(YEAR, [DateTime]) = {year} AND DATEPART(MONTH, [DateTime]) = {month}
END
Run Code Online (Sandbox Code Playgroud)
但这并没有改变事务日志的增长。接下来,我尝试在循环中使用显式事务。
WHILE @@ROWCOUNT > 0
BEGIN
BEGIN TRAN
DELETE TOP (1000000) FROM <sometable>
OUTPUT DELETED.* INTO [<sometable>_{year}_{month}]
WHERE DATEPART(YEAR, [DateTime]) = {year} AND DATEPART(MONTH, [DateTime]) = {month}
COMMIT
END
Run Code Online (Sandbox Code Playgroud)
再次。没有不同。更糟糕的是,如果我取消此查询并执行 ROLLBACK 以释放表,它会回滚所有内容。正如人们所期望的那样,不仅仅是最后一次迭代,而是整个过程。为什么循环中的各个事务没有被这样对待?当然,必须有一种方法可以在数据库中移动大量行,而 …