我们希望删除表中的大量过时数据,但这会长时间锁定表。是否可以使用Cursor删除,说,在while循环中每个事务一百条记录?
我在哪里可以参考这个例子?
答案 0 :(得分:2)
这样的事情:
DECLARE @stillgoing bit;
SET @stillgoing = 1;
WHILE @stillgoing = 1
BEGIN
DELETE TOP (100) YourTableName
WHERE IsObsolete = 1;
IF @@ROWCOUNT = 0
SET @stillgoing = 0;
CHECKPOINT /* Will encourage the log to clear if it's in Simple recovery model */
END
编辑:这只适用于SQL 2005及以上版本。正如我们刚刚学会的那样是SQL 2000,而不是这个代码:
DECLARE @stillgoing bit
SET @stillgoing = 1
SET ROWCOUNT 100
WHILE @stillgoing = 1
BEGIN
DELETE YourTableName
WHERE IsObsolete = 1
IF @@ROWCOUNT = 0
SET @stillgoing = 0
CHECKPOINT /* Will encourage the log to clear if it's in Simple recovery model */
END
并且...简单恢复模型意味着日志将在检查点上截断,而不是仅在备份日志时截断。
答案 1 :(得分:1)
你可以在循环中提交每100(或1000或其他)记录,释放锁并让任何待处理的操作得到它们的工作。否则你生成一个大于O的巨大事务日志(n ^ 2)变大的时间。这个东西将占用实际花费的很大一部分,而不是实际删除。如果批量和提交,你会更安全,回滚/日志文件不会像疯了一样增长,并且锁是可管理的。
如果您需要大量回滚作为选项,则有两种选择:
答案 2 :(得分:1)
Declare MyPrimaryKey [SomeType]
Declare @MyCursor Cursor For
Select MyPrimayKey from MyTable
Open @MyCursor
Fetch Next From @MyCursor
Into
@MyPrimaryKey
WHILE @@FETCH_STATUS = 0
BEGIN
WaitFor Delay '00:00:05'
Begin Transaction
DELETE From MyTable where MyPrimaryKey = @MyPrimaryKey
Commit Transaction
Fetch Next From @MyCursor
Into
@MyPrimaryKey
END