在TSQL中删除数百万条记录的最佳方法是什么?

在TSQL中删除数百万条记录的最佳方法是什么?,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有一个下表结构 Table1 Table2 Table3 -------------------------------- sId sId sId name x y x1 x2 x3 我想根据sId从表1中删除表3中没有匹配记录的所有记录,如果表2中存在sId,则不要从表1中删除记录。表1、表2和表3中分别有约20、15和1000万条记

我有一个下表结构

Table1       Table2        Table3
--------------------------------
 sId          sId           sId
 name          x              y
  x1          x2             x3
我想根据sId从表1中删除表3中没有匹配记录的所有记录,如果表2中存在sId,则不要从表1中删除记录。表1、表2和表3中分别有约20、15和1000万条记录。 --我做过类似的事情

Delete Top (3000000)
        From Table1 A
        Left Join Table2 B
        on A.Name ='XYZ' and
           B.sId = A.sId
        Left Join Table3 C
        on A.Name = 'XYZ' and
           C.sId = A.sId
Select * into #temp from mytable 
((我在sId上添加了索引,但没有在名称上添加。) 但这需要很长时间才能删除记录。 有没有更好的方法来删除数百万条记录?
提前感谢。

如果需要删除少于40%的数据,请以5000或10000为一批执行,如果需要更多数据,然后转储您想保留在另一个表中的数据/bcp out,请截断此表并再次插入您转储到另一个表中的行/bcp in

while @@rowcount > 0
begin
Delete Top (5000)
        From Table1 A
        Left Join Table2 B
        on A.Name ='XYZ' and
           B.sId = A.sId
        Left Join Table3 C
        on A.Name = 'XYZ' and
           C.sId = A.sId
end
您可以运行一个小示例来查看发生了什么

CREATE TABLE #test(id INT)

INSERT #test VALUES(1)
INSERT #test VALUES(1)
INSERT #test VALUES(1)
INSERT #test VALUES(1)
INSERT #test VALUES(1)
INSERT #test VALUES(1)
INSERT #test VALUES(1)

WHILE @@rowcount > 0
BEGIN 
DELETE TOP (2) FROM #test

END 

您是否在相关表字段上设置了适当的索引?如果没有,删除记录可能需要很长时间。

您正在执行的删除操作正在运行一个底层SELECT语句来查找将被删除的记录。您正在执行的操作基本上是一个简单的连接。如果优化该连接,最终删除也会更快


确保在进行连接的列上有索引。运行执行计划以确保它们正在使用

删除数百万条记录的一种方法是选择新表中的剩余记录,然后删除旧表并重命名新表。您可以根据外键选择最佳方式。您可以删除并重新创建外键,或者截断旧表中的数据,然后将选定的数据复制回来


如果您只需要删除少数记录,请忽略此答案。这是如果你真的想删除数百万条记录。

另一种方法是将你想保留的数据插入另一个表中,比如说Table1\u good。 完成并验证后: 删除表格1,然后将表格1重命名为表格1


使用top子句更能提高并发性,实际上可能会使代码运行变慢

一个建议是从派生表中删除数据:

清理完数据后,我会在表3上放置一个AFTER DELETE触发器,自动从表1中删除适用的记录。这样,您就可以实时清理数据,而不必删除大块数据。

我将创建一个临时表创建一个seleet并填充临时表,向临时表添加索引,并从我的表中删除我要删除的记录。当我做了这样的事情时,我会放下我的临时表

Delete Top (3000000)
        From Table1 A
        Left Join Table2 B
        on A.Name ='XYZ' and
           B.sId = A.sId
        Left Join Table3 C
        on A.Name = 'XYZ' and
           C.sId = A.sId
Select * into #temp from mytable 
在哪里胡说八道(或你的查询)

//如果你想的话,加上禁忌症

我会把主键插入临时表

那么我会说

删除mytable
主键在哪里(从#temp中选择myPrimarykey)

您的索引是什么样的?希望您的
sId
字段上有一个聚集索引?请参阅@JNK--是的,sId字段有聚集索引希望我能更快地键入。你赢了我。