全局临时表(GTT)

应用程序通常使用某种形式的临时数据存储,用于在单个过程中完成复杂的处理过程。通常,这些临时存储被定义为数据库表或PL / SQL表。 从Oracle 8i开始,可以使用全局临时表将临时表的维护和管理委派给服务器。

创建全局临时表

全局临时表中的数据是私有的,因此会话插入的数据只能由该会话访问。 可以为整个会话或仅为当前事务保留全局临时表中的会话特定行。

ON COMMIT DELETE ROWS子句表示应在事务结束时或会话结束时删除数据。

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>

相反,ON COMMIT PRESERVE ROWS子句指示行应该持续超出事务结束。 它们只会在会话结束时删除。

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>

全局临时表和Undo

虽然GTT中的数据被写入临时表空间,但是相关联的undo仍然写入正常的undo表空间,它本身由redo 保护,因此使用GTT不会减少与保护undo表空间相关联的undo和redo 。

以下代码创建一个常规表,填充它并检查事务使用的undo量。

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>

我们现在重复前面的测试,但这次使用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;

我们可以看到,使用的undo没有明显的区别。

Oracle 12c引入了Temporary Undo的概念,允许将GTT的undo写入临时表空间,从而减少undo 和redo

全局临时表和Redo

如果您阅读了上一节,您将已经知道全局临时表和redo之间的关系。 GTT中的数据写入临时表空间,不会被redo直接保护,因此使用GTT可以通过减少redo 生成来提高性能。 不幸的是,在Oracle 12c之前,与GTT相关的所有与DML相关的undo都被写入正常的undo表空间,这个表空间本身由redo保护。 因此,使用GTT减少了redo生成的数量,但不会消除它。 另一个描述这一点的原因是,使用GTT删除直接redo生成,而不是redo导致的间接重做生成。

以下代码创建一个常规表,填充它并检查事务生成的重做数量。

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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值