删除块中的大量行

时间:2017-01-19 17:35:10

标签: sql sql-server

我有大约8个表,每行有1000万行或更多,我想对它们进行最快/最优雅的删除。我决定一次删除它们。当我添加我的更改时,它看起来非常难看,并且想要知道如何将其格式化以使其看起来更好。另外,这是最好的方法吗?

DECLARE @ChunkSize int
SET @ChunkSize = 50000

WHILE @ChunkSize <> 0
BEGIN
  DELETE TOP (@ChunkSize) FROM TABLE1
  WHERE CREATED < @DATE
     SET @ChunkSize = @@rowcount
END


DECLARE @ChunkSize int
SET @ChunkSize = 50000

WHILE @ChunkSize <> 0
BEGIN
  DELETE TOP (@ChunkSize) FROM TABLE2
  WHERE CREATED < @DATE
     SET @ChunkSize = @@rowcount
END
.......

我会为所有8个表做这个似乎不实用的表。关于如何清理它的任何建议?

2 个答案:

答案 0 :(得分:1)

在2016 SP1之前,当分区仅在Enterprise中可用时,您可以批量删除,或者如果要删除的数据量与总数据相比较小,则可以将好数据复制到另一个表。

为了完成批处理工作,我会对你的代码提出一些建议,以便它更简单。

DECLARE @ChunkSize int
SELECT @ChunkSize = 50000 --use select instead of set so @@rowcount will <> 0

WHILE @@rowcount <> 0
BEGIN
  DELETE TOP (@ChunkSize) FROM TABLE1
  WHERE CREATED < @DATE
END

SELECT @ChunkSize = @ChunkSize --this will ensure that @@rowcount = 1 again.

WHILE @@rowcount <> 0
BEGIN
  DELETE TOP (@ChunkSize) FROM TABLE2
  WHERE CREATED < @DATE
END

您可能必须使用ChunkSize才能很好地处理数据,但50k是一个合理的起点。

答案 1 :(得分:1)

如果您想避免为每个表重复循环,可以使用动态SQL

IF OBJECT_ID('tempdb..#tableNames') IS NOT NULL DROP TABLE tempdb..#tableNames

SELECT name INTO #tableNames FROM sys.tables WHERE name IN (/* Names of tables you want to delete from */)

DECLARE @table varchar(50)
DECLARE @query nvarchar(max)

WHILE EXISTS (select '1' from #tableNames)
BEGIN

SET @table = (select top 1 name from #tableNames)
DELETE FROM #tableNames WHERE name = @table

SET @query = 'DECLARE @ChunkSize int
              SET @ChunkSize = 50000

              WHILE @ChunkSize <> 0
              BEGIN
                DELETE TOP (@ChunkSize) FROM ' + @table + '
                WHERE CREATED < @DATE
                   SET @ChunkSize = @@rowcount
              END'

EXEC sp_executesql @query
END