如何删除更快?

6 database oracle performance plsql

我有一个DB表,包含25亿条记录.有1100万的重复.删除这1100万条记录的最快方法是哪一种?

ska*_*man 20

从许多中删除一个副本是一件棘手的事情,有了这么多记录,你就会遇到问题.

一种选择是将问题放在首位,并将要保留的记录复制到新表中.您可以使用CREATE TABLE AS SELECT DISTINCT ... NOLOGGING语法,它将复制您的重复数据删除记录而不使用事务日志,这要快得多.填充新表后,删除/重命名旧表,并将新表重命名到位.

http://www.databasejournal.com/features/oracle/article.php/3631361/Managing-Tables-Logging-versus-Nologging.htm

哦,记得在新表上打一个UNIQUE索引,这样就不会再发生了.

这个故事的寓意是...... 永远不会使用DELETE来删除大量的记录,它的速度非常慢,因为它必须将所有已删除的记录存储在重做日志中.复制和切换,或TRUNCATE.

  • ...并且您可以将相同的算法应用于生产产品的团队,该团队仅允许11,000,000个重复行;-) Keith. (8认同)
  • 这个答案+1.我肯定会想要创建一个新的表副本并插入其中.我要添加的关键是,在复制数据之前,不要在该辅助表上放置任何索引 - 您不希望在插入数据时不必要地将索引保持在临时状态.我也喜欢这种方法,因为它有一个额外的安全网 - 你不必摆脱旧桌子,直到你100%确定你已经获得了所有正确的数据. (2认同)
  • 比较使用相同谓词复制2.489亿条记录与删除11百万条记录所需的时间比较有意思 (2认同)

Cha*_*ana 1

首先在定义并包含重复值的列上放置索引,

然后,假设该表有一个主键(PK),

  Delete Table T Where PK <> 
        (Select Min(PK) From Table
         Where ColA = T.ColA
           ...  for each column in set defined above
           And ColB = T.ColB)
Run Code Online (Sandbox Code Playgroud)

注意:也可以使用 Max(PK),您所做的只是识别一条记录,不要从每组重复项中删除

编辑:为了消除事务日志和UNDO分区的广泛使用,您可以将重复的值存储在临时表中,然后删除单个事务中每对的重复...

假设只有一列(称为 ColA,一个数字)定义了欺骗......

   Create Table Dupes (ColA Number)
   Insert Dupes(ColA)
   Select Distinct ColA
   From Table
   Group By ColA
   Having Count(*) > 1

   recordExists Number := 0 ;
   ColAValue Number;
   Select Case When Exists (Select Count(*) From Dupes)
   Then 1 Else 0 End Into recordExists From Dual;


   While recordExists = 1 
      Loop 
         Select (Select Max(ColA) From Dupes) 
         Into ColAValue From Dual;
         Begin Transaction
            Delete Table T
            Where ColA = ColAValue
               And pk <> (Select Min(Pk) From Table 
                          Where ColA = ColAValue);
            Delete Dupes Where ColA = ColAValue;
         Commit Transaction;
         Select Case When Exists (Select Count(*) From Dupes)
         Then 1 Else 0 End Into recordExists From Dual;
      End Loop;
Run Code Online (Sandbox Code Playgroud)

未经测试,因此语法可能需要调整......