简体   繁体   English

如何根据多种条件从SQL服务器删除大量数据

[英]How to delete large volume of data from SQL Server based on multiple condition

I am looking for a SQL query where I have to delete data from a table based on combination of 2 condition.我正在寻找一个 SQL 查询,我必须在其中根据 2 个条件的组合从表中删除数据。

I have a table dbo.ABC from which I have to delete the rows if combination of values pass as input present in column A and column B.我有一个表dbo.ABC ,如果值的组合作为 A 列和 B 列中的输入传递,我必须从中删除行。

Table - ABC表格 - ABC

column A   column B
===========================
100           US
200           IND

Now I have to delete record if column A is 100 and column B is US.现在,如果 A 列为 100 且 B 列为美国,我必须删除记录。 But I want to pass multiple inputs like 100 and 200 as column A and US and IND as column B respectively.但我想分别将 100 和 200 等多个输入作为 A 列传递,将 US 和 IND 作为 B 列传递。 100 and US will be the one combination to delete 1st record and 200 and IND will be the another combination to delete 2 record. 100 和 US 将是删除第 1 条记录的组合,200 和 IND 将是删除 2 条记录的另一种组合。 Similarly I want to pass 1000 input like this way to delete 1000 records in single shot rather than calling it 1000 times with single input.同样,我想像这样传递 1000 个输入,以单次删除 1000 条记录,而不是用单次输入调用它 1000 次。

Can I use multiple IN statement to delete the data as I have multiple combination of column_A and column_B ?我可以使用多个 IN 语句来删除数据,因为我有column_Acolumn_B的多个组合吗?

How to use for-loop to delete the data if I pass many combination of column_A and column_B ?如果我传递了column_Acolumn_B的许多组合,如何使用 for-loop 删除数据?

I am new to this field so not have much knowledge.我是这个领域的新手,所以没有太多知识。

Your help will be appreciated..您的帮助将不胜感激..

Thank you.谢谢你。

Please note: I have not debugged this.请注意:我没有调试过这个。 But I have used similar stuff for large-scale purge operations on a busy transactional database.但是我在繁忙的事务数据库上使用类似的东西进行大规模清除操作。

Create yourself a temporary table and populate it with the combinations you want to delete.为自己创建一个临时表并用要删除的组合填充它。 For example,例如,

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

Then do this to test your row-selection logic.然后执行此操作以测试您的行选择逻辑。 This should only return the rows you want to delete.这应该只返回您要删除的行。

SELECT TOP(500) ABC.*
  FROM ABC
  JOIN #to_delete d ON ABC.col1 = d.col1 AND ABC.col2 = d.col2;

Once you're satisfied this gets only the doomed rows, then do a so-called nibbling delete.一旦您对此感到满意,这只会得到注定的行,然后进行所谓的蚕食删除。 Repeat the delete query in a loop until it doesn't delete anything.在一个循环中重复删除查询,直到它不删除任何东西。 Like this.像这样。

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;

Why is this a good way to go?为什么这是到 go 的好方法?

  1. It deletes a small chunk of rows with each query, minimizing both the lock time for rows in the table and the size of each delete transaction.它会在每个查询中删除一小部分行,从而最大限度地减少表中行的锁定时间和每个删除事务的大小。
  2. The low deadlock priority is just insurance.低死锁优先级只是一种保险。 If one of these DELETE operations deadlocks with some other query, possibly on some index, we definitely want to kill the DELETE operation, not the other query.如果其中一个 DELETE 操作与其他查询发生死锁,可能是在某个索引上,我们肯定要终止 DELETE 操作,而不是其他查询。 We can just repeat the DELETE query.我们可以重复 DELETE 查询。
  3. The short delay between chunks allows your transactional workload to get time to run.块之间的短暂延迟允许您的事务性工作负载有时间运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM