如何根据多个条件从 SQL Server 中删除大量数据
Posted
技术标签:
【中文标题】如何根据多个条件从 SQL Server 中删除大量数据【英文标题】:How to delete large volume of data from SQL Server based on multiple condition 【发布时间】:2020-12-31 07:10:58 【问题描述】:我正在寻找一个 SQL 查询,我必须根据 2 个条件的组合从表中删除数据。
我有一个表 dbo.ABC
,如果值组合作为 A 列和 B 列中的输入传递,我必须从中删除行。
表格 - ABC
column A column B
===========================
100 US
200 IND
现在如果 A 列是 100 而 B 列是 US,我必须删除记录。但我想将多个输入(如 100 和 200)分别作为 A 列和 US 和 IND 作为 B 列。 100 和 US 将是删除第一条记录的一个组合,而 200 和 IND 将是另一个删除第二条记录的组合。同样,我想像这样传递 1000 个输入以单次删除 1000 条记录,而不是单次输入调用 1000 次。
column_A
和 column_B
有多个组合,我可以使用多个 IN 语句删除数据吗?
如果我通过column_A
和column_B
的多个组合,如何使用for循环删除数据?
我是这个领域的新手,所以知识不多。
您的帮助将不胜感激..
谢谢。
【问题讨论】:
请通过添加一些示例输入和输出数据来澄清您的问题。 您可以将所有记录组合添加到像物理表这样的暂存中,然后将表与您的实际表连接起来并删除匹配的记录 并且,不要在单个进程中删除大量记录。改为使用 Nibbling Delete。 (即:一次执行一个循环并删除 10000 条记录,....(这取决于您的并发工作量) @SQLServerBuddy:因为当您尝试删除 超过5000 行 在单个事务中,我建议您的批次一次小于 5000 行,以避免长时间锁定整个表 .... @marc_s 是的!根据并发进程和锁管理器的行为方式,这批记录可能会因环境而异。 【参考方案1】:请注意:我没有对此进行调试。但我在繁忙的事务数据库上使用了类似的东西进行大规模清除操作。
为自己创建一个临时表并使用要删除的组合填充它。例如,
CREATE TABLE #to_delete ( cola INT NOT NULL, colb NVARCHAR(200) NOT NULL);
GO
INSERT INTO #to_delete (cola, colb) VALUES
(100, N'US'),
(200, N'CN'),
(300, N'UK');
GO
然后执行此操作以测试您的行选择逻辑。这应该只返回您要删除的行。
SELECT TOP(500) ABC.*
FROM ABC
JOIN #to_delete d ON ABC.col1 = d.col1 AND ABC.col2 = d.col2;
一旦您感到满意,这只会得到注定要失败的行,然后执行所谓的蚕食删除。在循环中重复删除查询,直到它不删除任何内容。像这样。
DECLARE @count INT = 1;
WHILE @count > 0 BEGIN
WAITFOR DELAY '00:00:02';
BEGIN TRANSACTION;
SET DEADLOCK_PRIORITY LOW;
DELETE TOP(500) ABC
FROM ABC
JOIN #to_delete d ON ABC.col1 = d.col1 AND ABC.col2 = d.col2;
SET @count = @@ROWCOUNT;
COMMIT TRANSACTION;
END;
为什么这是一个好方法?
-
它会在每次查询时删除一小部分行,从而最大限度地减少表中行的锁定时间和每个删除事务的大小。
低死锁优先级只是保险。如果这些 DELETE 操作之一与其他查询(可能在某个索引上)发生死锁,我们肯定要终止 DELETE 操作,而不是其他查询。我们可以重复 DELETE 查询。
块之间的短暂延迟使您的事务工作负载有时间运行。
【讨论】:
以上是关于如何根据多个条件从 SQL Server 中删除大量数据的主要内容,如果未能解决你的问题,请参考以下文章
如何在 SQL Server 中使用 INNER JOIN 从多个表中删除