如何快速删除SQL数据库中的大量记录?
我们有一个大约150万条记录的表格。此表与不同表之间有许多FK关系 问题是100万条记录只是重复的,必须删除。我们试图一次删除1000条记录,但这是一个非常缓慢的过程 我的想法是将必须保留的记录临时复制到新表中。 截断现有记录并复制必须保留的记录。恢复主键和所有与其他表的关系。所以从客户端看,您看不到任何差异 不确定这是否是一种有效的方法 如果是的话,我希望看到它的基本实现,这样我就可以遵循并应用到我的案例中。 如果不是的话,我希望看到有效的方法如何快速删除SQL数据库中的大量记录?,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我们有一个大约150万条记录的表格。此表与不同表之间有许多FK关系 问题是100万条记录只是重复的,必须删除。我们试图一次删除1000条记录,但这是一个非常缓慢的过程 我的想法是将必须保留的记录临时复制到新表中。 截断现有记录并复制必须保留的记录。恢复主键和所有与其他表的关系。所以从客户端看,您看不到任何差异 不确定这是否是一种有效的方法 如果是的话,我希望看到它的基本实现,这样我就可以遵循并应用到我的案例中。 如果不是的话,我希望看到有效的方法 谢谢我们公司有一堆临时数据存储在数据库中。当我们
谢谢我们公司有一堆临时数据存储在数据库中。当我们需要删除一组数据时,我们会将其分成几百行,一次删除一个数据块。我们有一个应用程序,它的唯一用途是反复运行一些类似这样的查询:
with topFew as (select top 100 * from table) delete topFew
我建议你做一些像这样简单的事情,让它运行几个小时。在处理过程中,去做其他事情 通过使用rowid自加入表,可以提高删除的性能。它甚至可以通过使用批量收集和FORALL进行优化
DECLARE
limit_in integer;
CURSOR C1 is
Select min(b.rowid)
from table_name a, table_name b
where a.primary_key = b.primary_key;
TYPE C1_rec IS TABLE OF C1%ROWTYPE
INDEX BY PLS_INTEGER;
C1_record C1_rec
BEGIN
limit_in:=10000 --- Can be changed based on performance
OPEN C1;
LOOP
FETCH C1 BULK COLLECT INTO C1_record LIMIT limit_in;
FORALL indx in 1..c1_record.count
DELETE FROM table_name where row_id = C1_record(i);
commit;
END LOOP;
END;
要删除的表具有子表,因此将存在约束冲突
因此,在执行上述代码之前,最好修改外键约束,使其具有DELETE CASCADE。我们无法修改约束以添加-删除级联。因此,应该删除并重新创建外键,使其具有删除级联
ALTER child_table
ADD CONSTRAINT fk_name
foreign_key (C1)
references parent_table (C2) on delete cascade;
Delete cascade也会清理子表。这是一次性清理,还是您的系统有复制数据的习惯?您是否在列上有一个索引,可以过滤掉要删除的行?禁用索引,然后将唯一数据500K复制到表B中,然后截断并删除原始表,然后将B重命名为原始名称,然后继续indexes@German,就像索引一样,也添加关系,或者如果关系太多太复杂,禁用索引,将重复数据移动到表B中,然后重新创建索引(不启用),我认为,索引是您发现进程无法截断带有FKs的表的原因。是的,这一点很好,可以由第三方完成。第三方应用程序,将每个删除操作作为低优先级事务发送到数据库,我尝试投票赞成,但系统告诉我们今天已经足够了:这是一个Oracle解决方案,OP用SQL server标记了他的问题同样的概念也可以用在SQL server中。我不知道它是否那么容易翻译,我不知道SQL Server中的
rowid
和bulk collect
有任何现成的等价物