Applications often use some form of temporary data store for processes that are to complicated to complete in a single pass. Often, these temporary stores are defined as database tables or PL/SQL tables. From Oracle 8i onward, the maintenance and management of temporary tables can be delegated to the server by using Global Temporary Tables.
Related articles.
Oracle support two types of temporary tables.
The data in a global temporary table is private, such that data inserted by a session can only be accessed by that session. The session-specific rows in a global temporary table can be preserved for the whole session, or just for the current transaction.
The ON COMMIT DELETE ROWS
clause indicates the data should be deleted at the end of the transaction, or the end of the session.
CREATE GLOBAL TEMPORARY TABLE my_temp_table ( id NUMBER, description VARCHAR2(20) ) ON COMMIT DELETE ROWS; -- Insert, but don't commit, then check contents of GTT. INSERT INTO my_temp_table VALUES (1, 'ONE'); SELECT COUNT(*) FROM my_temp_table; COUNT(*) ---------- 1 SQL> -- Commit and check contents. COMMIT; SELECT COUNT(*) FROM my_temp_table; COUNT(*) ---------- 0 SQL>
In contrast, the ON COMMIT PRESERVE ROWS
clause indicates that rows should persist beyond the end of the transaction. They will only be removed at the end of the session.
CREATE GLOBAL TEMPORARY TABLE my_temp_table ( id NUMBER, description VARCHAR2(20) ) ON COMMIT PRESERVE ROWS; -- Insert and commit, then check contents of GTT. INSERT INTO my_temp_table VALUES (1, 'ONE'); COMMIT; SELECT COUNT(*) FROM my_temp_table; COUNT(*) ---------- 1 SQL> -- Reconnect and check contents of GTT. CONN test/test SELECT COUNT(*) FROM my_temp_table; COUNT(*) ---------- 0 SQL>
Although the data in a GTT is written to the temporary tablespace, the associated undo is still written to the normal undo tablespace, which is itself protected by redo, so using a GTT does not reduce undo and the redo associated with protecting the undo tablespace.
The following code creates a conventional table, populates it and checks the amount of undo used by the transaction.
DROP TABLE my_temp_table PURGE; -- Create conventional table. CREATE TABLE my_temp_table ( id NUMBER, description VARCHAR2(20) ); -- Populate table. INSERT INTO my_temp_table WITH data AS ( SELECT 1 AS id FROM dual CONNECT BY level < 10000 ) SELECT rownum, TO_CHAR(rownum) FROM data a, data b WHERE rownum <= 1000000; -- Check undo used by transaction. SELECT t.used_ublk, t.used_urec FROM v$transaction t, v$session s WHERE s.saddr = t.ses_addr AND s.audsid = SYS_CONTEXT('USERENV', 'SESSIONID'); USED_UBLK USED_UREC ---------- ---------- 302 6237 SQL>
We now repeat the previous test, but this time using a GTT.
DROP TABLE my_temp_table PURGE; -- Create GTT. CREATE GLOBAL TEMPORARY TABLE my_temp_table ( id NUMBER, description VARCHAR2(20) ) ON COMMIT PRESERVE ROWS; -- Populate GTT. INSERT INTO my_temp_table WITH data AS ( SELECT 1 AS id FROM dual CONNECT BY level < 10000 ) SELECT rownum, TO_CHAR(rownum) FROM data a, data b WHERE rownum <= 1000000; -- Check undo used by transaction. SELECT t.used_ublk, t.used_urec FROM v$transaction t, v$session s WHERE s.saddr = t.ses_addr AND s.audsid = SYS_CONTEXT('USERENV', 'SESSIONID'); USED_UBLK USED_UREC ---------- ---------- 303 6238 SQL> TRUNCATE TABLE my_temp_table;
We can see, there is no significant difference in the undo used.
Oracle 12c introduced the concept of Temporary Undo, allowing the undo for a GTT to be written to the temporary tablespace, thereby reducing undo and redo.
If you've read the previous section, you will already know the relationship between global temporary tables and redo. The data in a GTT is written to the temporary tablespace, which is not directly protected by redo, so using a GTT improves performance by reducing redo generation. Unfortunately, prior to Oracle 12c, all undo associated with DML against a GTT is written to the normal undo tablespace, which is itself protected by redo. As a result, using a GTT reduces the amount of redo generation, but does not eliminate it. Another why of describing this is, using a GTT removes direct redo generation, but not indirect redo generation cause by undo.
The following code creates a conventional table, populates it and checks the amount of redo generated by the transaction.
DROP TABLE my_temp_table PURGE; -- Create conventional table. CREATE TABLE my_temp_table ( id NUMBER, description VARCHAR2(20) ); SET AUTOTRACE ON STATISTICS; -- Populate table. INSERT INTO my_temp_table WITH data AS ( SELECT 1 AS id FROM dual CONNECT BY level < 10000 ) SELECT rownum, TO_CHAR(rownum) FROM data a, data b WHERE rownum <= 1000000; 1000000 rows created. Statistics ---------------------------------------------------------- 106 recursive calls 20119 db block gets 2603 consistent gets 16 physical reads 23039396 redo size 853 bytes sent via SQL*Net to client 987 bytes received via SQL*Net from client 3 SQL*Net roundtrips to/from client 6 sorts (memory) 0 sorts (disk) 1000000 rows processed SQL>
We now repeat the previous test, but this time using a GTT.
DROP TABLE my_temp_table PURGE; -- Create GTT. CREATE GLOBAL TEMPORARY TABLE my_temp_table ( id NUMBER, description VARCHAR2(20) ) ON COMMIT PRESERVE ROWS; SET AUTOTRACE ON STATISTICS; -- Populate GTT. INSERT INTO my_temp_table WITH data AS ( SELECT 1 AS id FROM dual CONNECT BY level < 10000 ) SELECT rownum, TO_CHAR(rownum) FROM data a, data b WHERE rownum <= 1000000; 1000000 rows created. Statistics ---------------------------------------------------------- 45 recursive calls 15333 db block gets 2381 consistent gets 16 physical reads 2944180 redo size 862 bytes sent via SQL*Net to client 987 bytes received via SQL*Net from client 3 SQL*Net roundtrips to/from client 5 sorts (memory) 0 sorts (disk) 1000000 rows processed SQL> TRUNCATE TABLE my_temp_table;
We can see we have created an order of magnitude less redo when using the GTT, but we have not eliminated it.
A new variation of temporary tables has been introduced in Oracle 18c. A private temporary table is a memory-based temporary table that is dropped at the end of the session or transaction depending on the setup. You can read more about them here.
For more information see:
Hope this helps. Regards Tim...
Back to normal view: https://oracle-base.com/articles/misc/temporary-tables