我正在处理客户端的数据库,由于软件中的错误,需要删除大约100万行。是否有一种有效的方法来删除它们:
DELETE FROM table_1 where condition1 = 'value' ?
答案 0 :(得分:59)
这是上面建议的批量删除的结构。不要一次尝试1M ......
批处理的大小和waitfor延迟显然是可变的,并且取决于您的服务器功能以及缓解争用的需要。您可能需要手动删除某些行,测量它们的耗时,并将批量大小调整为服务器可以处理的内容。如上所述,超过5000的任何东西都可能导致锁定(我不知道)。
这最好在数小时之后完成......但是对于SQL来说,1M行真的不是很多。如果您在SSMS中观看消息,可能需要一段时间才能显示打印输出,但是经过几批后,请注意它不会实时更新。
修改:添加了停止时间@MAXRUNTIME
& @BSTOPATMAXTIME
。如果您将@BSTOPATMAXTIME
设置为1,则脚本将在所需的时间停留在其上,例如上午8:00。通过这种方式,您可以在夜间开始计划,并在早上8点开始生产。
编辑:答案非常受欢迎,因此我每次评论都添加RAISERROR
代替PRINT
。
DECLARE @BATCHSIZE INT, @WAITFORVAL VARCHAR(8), @ITERATION INT, @TOTALROWS INT, @MAXRUNTIME VARCHAR(8), @BSTOPATMAXTIME BIT, @MSG VARCHAR(500)
SET DEADLOCK_PRIORITY LOW;
SET @BATCHSIZE = 4000
SET @WAITFORVAL = '00:00:10'
SET @MAXRUNTIME = '08:00:00' -- 8AM
SET @BSTOPATMAXTIME = 1 -- ENFORCE 8AM STOP TIME
SET @ITERATION = 0 -- LEAVE THIS
SET @TOTALROWS = 0 -- LEAVE THIS
WHILE @BATCHSIZE>0
BEGIN
-- IF @BSTOPATMAXTIME = 1, THEN WE'LL STOP THE WHOLE JOB AT A SET TIME...
IF CONVERT(VARCHAR(8),GETDATE(),108) >= @MAXRUNTIME AND @BSTOPATMAXTIME=1
BEGIN
RETURN
END
DELETE TOP(@BATCHSIZE)
FROM SOMETABLE
WHERE 1=2
SET @BATCHSIZE=@@ROWCOUNT
SET @ITERATION=@ITERATION+1
SET @TOTALROWS=@TOTALROWS+@BATCHSIZE
SET @MSG = 'Iteration: ' + CAST(@ITERATION AS VARCHAR) + ' Total deletes:' + CAST(@TOTALROWS AS VARCHAR)
RAISERROR (@MSG, 0, 1) WITH NOWAIT
WAITFOR DELAY @WAITFORVAL
END
答案 1 :(得分:11)
BEGIN TRANSACTION
DoAgain:
DELETE TOP (1000)
FROM <YourTable>
IF @@ROWCOUNT > 0
GOTO DoAgain
COMMIT TRANSACTION
答案 2 :(得分:4)
这是我用过的东西:
如果错误数据与good-
混合在一起INSERT INTO #table
SELECT columns
FROM old_table
WHERE statement to exclude bad rows
TRUNCATE old_table
INSERT INTO old_table
SELECT columns FROM #table
答案 3 :(得分:3)
不确定这会有多好但是如果你喜欢下面的内容(假设table_1
是一个独立的表;我的意思是没有其他表引用)
创建table_1
的重复表格,如table_1_dup
insert into table_1_dup select * from table_1 where condition1 <> 'value';
drop table table_1
sp_rename table_1_dup table_1
答案 4 :(得分:3)
也许是Uri Dimant的解决方案
WHILE 1 = 1
BEGIN
DELETE TOP(2000)
FROM Foo
WHERE <predicate>;
IF @@ROWCOUNT < 2000 BREAK;
END
答案 5 :(得分:2)
如果您在维修时无法承受数据库的生产,请小批量生产。另见:How to efficiently delete rows while NOT using Truncate Table in a 500,000+ rows table
如果您赶时间并且需要尽可能快的方式:
答案 6 :(得分:0)
信不信由你,我的桌子上有300万个50万条记录
我写了这句话
DELETE TOP(500000) FROM MyTable
,我手动执行了大约7次, 每次执行大约需要50秒,但是最终,这解决了问题
答案 7 :(得分:0)
您可以用来立即删除表中的所有数据
truncate Table_Name