sql - 删除oracle表: size is 389 GB中的重复记录

标签 sql database oracle truncate

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

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

列详细信息:

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

表的大小:386 GB

数据库详细信息: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可以换成3,反之亦然。

我的计划是

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

由于数据量巨大,

  1. 想知道什么是用于检索不同的优化的 sql 记录
  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 个表分区。

关于sql - 删除oracle表: size is 389 GB中的重复记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19739926/

相关文章:

oracle - 如何将 Oracle PL/SQL 包中的电子邮件发送给多个收件人?

MySQL嵌套选择查询?

sql - 即使 autocommit=True,INSERT 和 UPDATE 语句也没有效果

c++ - QSqlite 在 Windows 和 Linux 上的不同行为

php - 如何在 PHP Laravel Lumen 中建立与数据库的连接?

sql - PLSQL 触发器错误。 "is mutating, trigger/function may not see it"ORA-04091

sql - 为什么使用 "where rownum = 1"不选择第一个有序行?

sql - 过滤具有相同 ID 的前一行具有特定值的数据

database - Laravel DB 查询生成器 "whereNotIn"到另一个表

java - 在oracle中的数字字段中输入空值