Oracle needs UNDO information to roll back DML in a transaction. As Gary says in his comment:
βUNDO is needed to rollback the effects of a single statement if it fails. It is also necessary to provide a ROLLB SAVEPOINT or ROLLBACK (although for GLOBAL TEMPORARY TABLES only GTT duration sessions will be relevant).
This UNDO information itself generates REDO. You can do nothing in this situation: temporary tables need UNDO at the end of this.
To minimize the number of UNDOs, it's simple enough: just insert records and select records. INSERT generates the least amount of UNDO because rolling back INSERT requires just a rowid. Conversely, DELETE statements generate most UNDOs because the database must store the entire record. Basically, for an INSERT rollback, a DELETE problem so that a DELETE rollback returns INSERT. UPDATE generates a UNDO variable amount because we need older versions of the modified columns; the more columns are changed and the larger they are, the greater the number of UNDOs will be.
Demonstration
In the first session, the user inserts many records into the temporary table, and then deletes them. In the second session, the DBA will track the use of the UNDO transaction.
SSN1> insert into gtt23 2 select * from big_table 3 / 553928 rows created. SSN1>
Cancel use:
SSN2> select space, noundo, used_ublk, used_urec from v$transaction 2 / SPA NOU USED_UBLK USED_UREC --- --- ---------- ---------- NO NO 257 10816 SSN2>
Now removal:
SSN1> delete from gtt23 2 / 553928 rows deleted. SSN1>
Cancel use (some examples while working with a large number of operators) ::
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>
Commit (the temporary table has a transaction scope, i.e. DELETE ROWS)
SSN1> commit 2 / Commit complete. SSN1>
Cancel use:
SSN2> r 1* select space, noundo, used_ublk, used_urec from v$transaction no rows selected SSN2>
Using cancellation is cumulative:
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>
Cancel use
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>
Summary
Thus, to minimize the impact of the UNDO that the temporary table generates, make sure you insert the data you want once. Avoid applying updates to it and especially avoid deleting a large number of entries from them. If you are using a temporary table with a transaction scope, there really should not be a need to delete records from it. If your temporary table has a session duration and you need to clear it, it would be better to use TRUNCATE, if possible, rather than DELETE.