ska*_*man 20
从许多中删除一个副本是一件棘手的事情,有了这么多记录,你就会遇到问题.
一种选择是将问题放在首位,并将要保留的记录复制到新表中.您可以使用CREATE TABLE AS SELECT DISTINCT ... NOLOGGING语法,它将复制您的重复数据删除记录而不使用事务日志,这要快得多.填充新表后,删除/重命名旧表,并将新表重命名到位.
哦,记得在新表上打一个UNIQUE索引,这样就不会再发生了.
这个故事的寓意是...... 永远不会使用DELETE来删除大量的记录,它的速度非常慢,因为它必须将所有已删除的记录存储在重做日志中.复制和切换,或TRUNCATE.
首先在定义并包含重复值的列上放置索引,
然后,假设该表有一个主键(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)
未经测试,因此语法可能需要调整......