Oracle DELETE 破坏 TEMP space

Oracle DELETE busting TEMP space

我有一个 table 有 170 亿行。我想删除其中一些,存在于另一个 table.

我尝试了一个并行化的删除语句,但没有完成,因为临时 space 不够。

delete /* + PARALLEL(a, 32) */
  from a
 where (a.key1, a.key2) in
         (select /*+ PARALLEL(b, 16) */
                 key1,
                 key2
            from b);

然后我尝试将 table 创建为 select,但由于同样的原因也失败了。

create table a_temp parallel 32 nologging as
       select /* + PARALLEL (a, 32) */
              key1,
              key2,
              rest_of_data
         from a
        where (a.key1, a.key2) not in
                (select key1, key2 from b);

常规(没有 PARALLEL)删除需要一天以上的时间,所以我不得不终止它。

有没有办法在删除执行期间释放临时 space,因为它不再需要了?

还有其他方法吗?

编辑: B 有 1.73 亿条记录,将近 160 亿条记录要删除(几乎是整个table)。 table.

上没有索引

编辑2: 创建table的解释计划如下:

CREATE TABLE STATEMENT, GOAL = ALL_ROWS         6749420 177523935   10828960035
 PX COORDINATOR                 
  PX SEND QC (RANDOM)   SYS :TQ10001    6740915 177523935   10828960035
   LOAD AS SELECT (HYBRID TSM/HWMB) USER    A_TEMP          
    OPTIMIZER STATISTICS GATHERING          6740915 177523935   10828960035
     MERGE JOIN ANTI NA         6740915 177523935   10828960035
      SORT JOIN         6700114 17752393472 745600525824
       PX BLOCK ITERATOR            45592   17752393472 745600525824
        TABLE ACCESS FULL   USER    A   45592   17752393472 745600525824
      SORT UNIQUE           40802   173584361   3298102859
       PX RECEIVE           5365    173584361   3298102859
        PX SEND BROADCAST   SYS :TQ10000    5365    173584361   3298102859
         PX BLOCK ITERATOR          5365    173584361   3298102859
          TABLE ACCESS FULL USER    B   5365    173584361   3298102859

提前致谢

以前为了解决这个问题,我都是一次批量删除~1M。在为更清洁的解决方案进行了大量挖掘之后,一位 DBA 坚持要我采用这种方法。

这是我的工作流程:

我使用 Python 和 cx_Oracle 模块读取要删除的记录的 PK 值,迭代地将它们作为绑定变量插入到 executemany 调用中,并在每次迭代后提交。

如果您想坚持使用并行执行方法: 请记住使用 ALTER SESSION ENABLE PARALLEL DML 以便您的合并或删除也可以并行执行。查看这个很棒的博客 post,它会引导您完成此操作: https://dioncho.wordpress.com/2010/12/10/interpreting-parallel-merge-statement/

我使用不同的解决方案使它起作用。

我手动创建了 a_temp table 并做了 insertAPPEND PARALLEL 提示。没有超过温度 space,插入表现完美。

代码如下:

create table a_temp(..);

insert /* + APPEND PARALLEL(a_temp, 32) */
  into a_temp(...)
select /* + PARALLEL(a, 32) */
       (...)
  from a
 where not exists
       (select /* + PARALLEL(b, 16) */
               '1'
          from b
         where a.key1 = b.key1
           and a.key2 = b.key2)