如何在Oracle临时表上使用DML而不生成大量撤消日志

Sam*_*rum 4 oracle plsql

使用Oracle临时表不会生成大量重做日志作为普通表.但是,仍会生成撤消日志.因此,如何在临时表上编写插入,更新或删除语句,但Oracle不会生成撤消日志或尽可能少生成?

而且,在insert语句中使用/ + append /将生成很少的撤消日志.我对么?如果没有,有人可以解释我使用提示/ +追加 /?

INSERT /*+APPEND*/ INTO table1(...) VALUES(...);
Run Code Online (Sandbox Code Playgroud)

APC*_*APC 12

Oracle需要UNDO信息来回滚事务中的DML.正如加里在评论中所说:

"如果单个语句中途失败,则需要回滚单个语句的效果.还需要提供ROLLBACK TO SAVEPOINT或ROLLBACK(尽管对于GLOBAL TEMPORARY TABLES,后者仅与会话持续时间GTT相关) ".

该UNDO信息本身产生REDO.关于这种情况你无能为力:临时表需要UNDO,这就是它的结束.

最小化UNDO的数量非常简单:只需插入记录并选择记录.INSERT生成最小量的UNDO,因为回滚INSERT只需要rowid.相反,DELETE语句生成最多的UNDO,因为数据库必须存储整个记录.基本上,要回滚INSERT问题DELETE,要回滚DELETE问题INSERT.UPDATE生成可变数量的UNDO,因为我们需要更改列的旧版本; 更改的列越多,它们越大,UNDO生成的数量越大.

示范

在会话一中,用户将大量记录插入临时表中,然后将其删除.在第二部分中,DBA将监视事务的UNDO使用情况.

SSN1> insert into gtt23
  2      select * from big_table
  3  /

553928 rows created.

SSN1>
Run Code Online (Sandbox Code Playgroud)

撤消用法:

SSN2> select space, noundo, used_ublk, used_urec from v$transaction
   2  /

SPA NOU  USED_UBLK  USED_UREC
--- --- ---------- ----------
NO  NO         257      10816

SSN2>
Run Code Online (Sandbox Code Playgroud)

现在删除:

SSN1> delete from gtt23
   2  /

553928 rows deleted.

SSN1>
Run Code Online (Sandbox Code Playgroud)

撤消使用(长时间运行语句中的几个样本)::

SSN2> r
   1* select space, noundo, used_ublk, used_urec from v$transaction

SPA NOU  USED_UBLK  USED_UREC
--- --- ---------- ----------
NO  NO       11123     435605

SSN2> r
   1* select space, noundo, used_ublk, used_urec from v$transaction

SPA NOU  USED_UBLK  USED_UREC
--- --- ---------- ----------
NO  NO       13413     525452

SSN2> r
   1* select space, noundo, used_ublk, used_urec from v$transaction

SPA NOU  USED_UBLK  USED_UREC
--- --- ---------- ----------
NO  NO       14552     570567

SSN2>
Run Code Online (Sandbox Code Playgroud)

提交(临时表具有事务范围,即DELETE ROWS)

SSN1> commit
   2  /

Commit complete.

SSN1>
Run Code Online (Sandbox Code Playgroud)

撤消用法:

SSN2> r
   1* select space, noundo, used_ublk, used_urec from v$transaction

no rows selected

SSN2>
Run Code Online (Sandbox Code Playgroud)

撤消使用是累积的:

SSN1> insert into gtt23
   2      select * from big_table
   3  /

553928 rows created.

SSN1> delete from gtt23
   2  /

553928 rows deleted.

SSN1> insert into gtt23
   2      select * from big_table
   3  /

553928 rows created.

SSN1>
Run Code Online (Sandbox Code Playgroud)

撤消使用情况

SSN2> r
   1* select space, noundo, used_ublk, used_urec from v$transaction

SPA NOU  USED_UBLK  USED_UREC
--- --- ---------- ----------
NO  NO         258      10816

SSN2> r
   1* select space, noundo, used_ublk, used_urec from v$transaction

SPA NOU  USED_UBLK  USED_UREC
--- --- ---------- ----------
NO  NO       14766     579495

SSN2> r
   1* select space, noundo, used_ublk, used_urec from v$transaction

SPA NOU  USED_UBLK  USED_UREC
--- --- ---------- ----------
NO  NO       14819     581685

SSN2>
Run Code Online (Sandbox Code Playgroud)

摘要

因此,为了最小化临时表生成的UNDO的影响,请确保插入一次正确的数据.避免对其应用更新,尤其要避免从中删除大量记录.如果您使用的是具有事务范围的临时表,则实际上不需要从中删除记录.如果您的临时表具有会话持续时间并且您需要清除它,那么最好使用TRUNCATE(如果可能),而不是DELETE.