需要从表中删除重复记录。表中包含33列,只有PK_NUM
是主键列。由于PK_NUM
包含唯一记录,我们需要考虑最小值/最大值。
列详细信息:
表格大小:386 GB
数据库详细信息:Oracle Database 11g EE :: 11.2.0.2.0 :: 64bit Production
示例数据:
预期数据应仅包含2条记录:
* 1可以替换为3,反之亦然。
我的计划是
由于数据量巨大,
请告诉我,如果有其他最好的方法可以实现这一点。我的最终目标是删除重复项。
答案 0 :(得分:2)
使这种内存有效的一个选项是将所有行插入(nologging append)到一个表中,该表在要检测重复项的列的列表上进行散列分区,或者如果数量有限制然后使用尽可能多的列(旨在使用具有最大选择性的列)。使用类似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个表分区。舍入到最接近的2的幂,所以在这种情况下使其成为256个表分区。
答案 1 :(得分: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并不像整个group by在将要创建新表的目标表空间中发生的那样多。完成后,您可以删除带有重复项的那个:
drop table table_name_dup;