2013-11-02 51 views
3

需要删除表中的重复记录。表中仅包含其中的33列PK_NUM是主键列。由于PK_NUM包含独特的记录,我们需要考虑最小值/最大值。删除oracle表中的重复记录:大小为389 GB

  1. 总表中的记录:1766799022个
  2. 鲜明表中的记录:69237983个
  3. 重复表中的记录:1697561039个

柱细节:

  • 4:日期数据类型
  • 4:数字数据类型
  • 1:Char数据类型
  • 24:VARCHAR2数据类型

工作台尺寸:386 GB

DB细节:Oracle数据库11g EE :: 11.2.0.2.0 :: 64位生产

的样本数据:

  • COL1,COL2,COL3
  • 1,ABC,123
  • 2,PQR,456
  • 3,ABC,123个

预期数据应仅包含2记录:

  • COL1,COL2,COL3
  • 1 ,ABC,123
  • 2,PQR,456

* 1可被取代d乘以3,反之亦然。

我在这里的计划是

  1. 拉不重复的记录,并将其存储在备份表(通过使用插入即进入选)
  2. 截断现有表和移动从后最多记录现有的。

由于数据量庞大,

  1. 想知道什么是提取不同 记录
  2. 上要花费多少才能完成任何估计优化的SQL(插入 选择)并截断现有的表。

请让我知道,如果有任何其他最好的办法来实现这一点。我的最终目标是删除重复项。

+1

根据我的经验,插入将比删除快很多。所以你的方法听起来不错。当您将原始表格和备份放到旧名称并重新创建所有约束时,可以更快地完成。然后保存重新插入行的工作 –

+0

需要多少个列来区分独特性? –

+0

需要15列来比较清晰度 –

回答

1

试试这个:

rename table_name to table_name_dup; 

然后:

create table table_name 
as 
select 
    min(col1) 
, col2 
, col3 
from table_name_dup 
group by 
    col2 
, col3; 

据我所知使用的temp_tablespace没有太大作为整个集团的正在发生的目标表,其中新表将被创建。一旦完成,你可以放下一个与重复:

drop table table_name_dup; 
+0

[排序和哈希在临时表空间中完成](http://docs.oracle.com)。 COM/CD/E11882_01/server.112/e40540/physical.htm#CNCPT1112)。该操作将需要大约389GB的临时表空间。 –

+0

389 GB临时表空间不可用按照我的DBA ...任何其他解决方法请 –

+0

在我的答案中查看散列分区建议。如果您有可用的分区,那么它将大大减少您的临时分类需求。 –

2

使这次的内存使用效率的一个选择是插入(NOLOGGING追加)中的所有行到一个表列的名单上被哈希分区的在其上检测重复,或者如果列数有限制,则尽可能多地使用(旨在使用具有最大选择性的那些)。使用类似1024分区的分区,并且每个分区最好在

以上

然后,您已将每行的所有潜在重复项隔离到同一个分区中,并且重复数据删除的标准方法将在每个分区上运行,而没有消耗太多的内存。

因此,对于每个分区,你可以这样做......

insert /*+ append */ into new_table 
select * 
from temp_table partition (p1) t1 
where not exists (
     select null 
     from temp_table partition (p1) t2 
     where t1.col1 = t2.col1 and 
       t1.col2 = t2.col2 and 
       t1.col3 = t2.col3 and 
       ... etc ... 
       t1.rownum < t2.rownum); 

在这里表现良好的关键是在查询创建执行哈希表抗加盟,这将是几乎与分区本身一样大,能够适应内存。因此,如果您可以管理2GB的排序区域,则至少需要389/2 =大约200个表分区。四舍五入到最接近的两个幂,所以在这种情况下使用256个表分区。