3

需要从表中删除重复记录。表包含 33 列,其中只有PK_NUM主键列。由于PK_NUM包含唯一记录,我们需要考虑最小值/最大值。

  1. 表中记录总数:1766799022
  2. 表中的不同记录:69237983
  3. 表中重复记录:1697561039

栏目详情:

  • 4:日期数据类型
  • 4:数字数据类型
  • 1:字符数据类型
  • 24 : Varchar2 数据类型

表大小:386 GB

数据库详细信息:Oracle Database 11g EE::11.2.0.2.0 ::64bit Production

样本数据 :

  • 科尔1,科尔2,科尔3
  • 1,ABC,123
  • 2,PQR,456
  • 3,ABC,123

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

  • col1,col2,col3
  • 1,ABC,123
  • 2,PQR,456

*1 可以用 3 代替,反之亦然。

我的计划是

  1. 提取不同的记录并将其存储在备份表中。(即通过使用插入到选择中)
  2. 截断现有表并将记录从备份移动到现有表。

由于数据量巨大,

  1. 想知道检索不同记录的优化 sql 是什么
  2. 关于完成(插入选择)和截断现有表所需的任何估计。

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

4

2 回答 2

2

提高内存效率的一种选择是将所有行插入(不记录附加)到一个表中,该表在要检测重复的列列表上进行散列分区,或者如果列数有限制,则尽可能多地使用(旨在使用具有最大选择性的那些)。使用 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 个表分区。

于 2013-11-03T08:58:11.757 回答
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;
于 2013-11-02T16:46:45.440 回答