JCB*_*JCB 16 sql sql-server rowcount
我有一个非常大的表,所以我使用以下内容删除旧条目:
WHILE (@@ROWCOUNT > 0)
BEGIN
DELETE TOP (5000) FROM myTable
WHERE date < 20130103
END
Run Code Online (Sandbox Code Playgroud)
我使用不同的日期运行了几次.有时它工作正常(大约需要20分钟),但有时候查询会立即完成,并且没有删除任何内容.当发生这种情况时,我只是从该表中执行一个简单的SELECT语句,然后再次尝试上面的WHILE语句,然后它就可以了!有谁知道这是为什么?我需要自动执行此查询以定期运行以控制表大小,但我想确保它在运行时实际上正确删除.谢谢.
Mic*_*son 33
在这段代码之前你在运行什么? @@ROWCOUNT将被设置为进行它的任何语句..如果你事先运行其他命令,它可能是0.
相反,您可以强制初始计数为1:
DECLARE @Rows INT
SET @Rows = 1
WHILE (@Rows > 0)
BEGIN
DELETE TOP (5000) FROM myTable
WHERE date < 20130103
SET @Rows = @@ROWCOUNT
END
Run Code Online (Sandbox Code Playgroud)
Gor*_*off 10
据推测,原因是因为@@ROWCOUNT初始化为0.
您可以先运行此查询来设置它:
select count(*) from myTable where date < 20130103
Run Code Online (Sandbox Code Playgroud)
这会为您的查询添加一点时间,但您会看到要删除的行数.
你也可以这样做:
select top 1 * from myTable
Run Code Online (Sandbox Code Playgroud)
哪个会快得多.
这是因为有时候@@ROWCOUNT开始时为零 - 所以while循环永远不会执行,因为它会在每次执行之前检查条件,包括第一个.
这是一个自制的do-while循环,因为SQL Server没有内置的循环.
loop:
DELETE TOP (5000) FROM myTable
WHERE date < 20130103
if @@ROWCOUNT > 0 goto loop
Run Code Online (Sandbox Code Playgroud)
当我批量删除时,我添加了 WAITFOR DELAY(至少 1 或 2 秒)。也是我在循环外创建的第一条语句。顺便说一句,避免使用 ROWCOUNT 作为分隔符(https://docs.microsoft.com/en-us/sql/t-sql/statements/set-rowcount-transact-sql?view=sql-server-2017)。有两个选项:
DECLARE @BatchSize BIGINT = 50000
SET ROWCOUNT @BatchSize
DELETE
FROM myTable
WHERE
date < 20130103
WHILE (@@ROWCOUNT > 0)
BEGIN
WAITFOR DELAY '00:00:02'
DELETE
FROM myTable
WHERE
date < 20130103
END
Run Code Online (Sandbox Code Playgroud)
或者
DECLARE @BatchSize BIGINT = 50000
WHILE 1=1
BEGIN
WAITFOR DELAY '00:00:02'
DELETE TOP(@BatchSize )
FROM myTable
WHERE
date < 20130103
IF @@ROWCOUNT < @BatchSize
Break
END
Run Code Online (Sandbox Code Playgroud)