运行并行删除语句

use*_*027 4 sql-server delete sql-server-2012

问题:我有一张很大的桌子 - 占用了高达 9.5 TB 的空间。我需要从中删除大约 500 万行。我想出的最好方法在 2 小时内删除了 100 万条记录!由于我无法在高峰时间运行此程序,因此我每天只有 2 小时的时间窗口,以这种速度删除 500 万行需要 4 个工作日。

问:我想知道 SQL Server 是否具有可以同时对一个表运行 2 个或多个删除的功能。可能类似于虚拟分区表 - 不确定。

我还想补充一点,运行我的脚本会导致页面锁定,但会阻止事务日志增长。我的脚本与 vonPryz 建议的脚本非常相似:

如何在不增加事务日志的情况从大表中批量删除Greg M Lucas。

Tho*_*ser 10

让我尝试根据上面的评论者总结答案。

首先,要实现更高的删除速度,您可以做三件事:

  1. 一次删除更多行
  2. 使用分区
  3. 运行多次删除

广告 1)由于一次删除大量行会严重影响事务日志并导致锁定 - 您可能希望语句中的删除次数为“小”。我发现大约 10K 行是一个很好的数字(并且关闭了表锁升级ALTER TABLE Foo SET LOCK_ESCALATION = Disabled

广告 2)如果您的表尚未分区,这不是一个选项

广告 3) SQL Server 中的 DELETE 是单线程的,因此您需要一次运行多个才能获得最大速度。要同时运行多个删除,您需要一种对它们进行分区的方法,以便每个并行删除运行在它自己的一组键上并且不会与其他键阻塞。通常,您可以使用表的主键进行分区删除。

例如,如果您key在表上调用了 IDENTITY 列,您可以先:

SELECT MAX(key) - MIN(key), MIN(key) FROM Foo WHERE <rows that must be deleted>
Run Code Online (Sandbox Code Playgroud)

保持最大值-最小值和闵某(tempdb中的表),您可以快速地从成变量中读取@IntervalSize@MinKey分别。

假设您决定可以分配 4 个内核来运行删除。您现在运行 4 个查询,来自 4 个 SSMS 新查询或通过 SQLCMD 的四个命令提示符,每个查询都执行以下操作:

DECLARE @NumDone INT = 1
WHILE @NumDone > 0 BEGIN
  SET ROWCOUNT 10000

  DELETE FROM Foo WHERE Key BETWEEN @MinKey + @IntervalSize / 4 * @n 
     AND @MinKey + @IntervalSize / 4 (@n + 1)
  SET @NumDone = @@ROWCOUNT
END
Run Code Online (Sandbox Code Playgroud)

为每个同时运行的 DELETES 选择 @n = 0,1,2,3。