如何快速从SQL数据库中删除大量记录?

时间:2013-06-29 16:37:54

标签: sql sql-server sql-server-2008

我们有一张约有150万条记录的表格。该表与不同的表有很多FK关系。

问题是100万条记录只是必须删除的重复记录。我们当时尝试删除1000条记录,但这是一个非常缓慢的过程。

我的想法是临时复制必须留在新表中的记录。 截断现有的并复制必须留下的记录。将主键和所有关系还原到其他表。所以从客户端来看,你看不出任何差异。

不确定这是否有效。

如果我希望看到它的基本实现,那么我可以关注并适用于我的案例。 如果不是,我希望看到有效的方法。

谢谢

2 个答案:

答案 0 :(得分:2)

我们公司有一堆临时数据存储在数据库中。当我们需要删除一堆它们时,我们将它分成几百行并一次删除它们。我们有一个应用程序,它的唯一目的是一遍又一遍地运行这样的一些查询:

with topFew as (select top 100 * from table) delete topFew

我建议你掀起像这样简单的东西,让它运行几个小时。在处理过程中继续处理其他事情。

答案 1 :(得分:1)

使用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;

要删除的表具有子表,因此将存在约束违规。

因此,在执行上面的代码之前,更改外键约束TO HAVE DELETE CASCADE是一个更好的选择。我们无法修改约束来添加删除级联。因此应删除外键并重新创建以删除级联

    ALTER child_table
    ADD CONSTRAINT fk_name
    foreign_key (C1)
    references parent_table (C2) on delete cascade;

删除级联也会清理你的子表..