代码之家  ›  专栏  ›  技术社区  ›  user78706

Oracle 10g临时表

  •  1
  • user78706  · 技术社区  · 15 年前

    我正在尝试将存储过程中使用的永久表转换为全局临时表。我已经查看了这些永久表的统计数据,其中一些表有数以千万计的数据行,并且按大小排列(最高10 GB)。

    所以,

    CREATE TABLE my_table (  
      column1 NUMBER,  
      column2 NUMBER,  
      etc...  
    )  
    TABLESPACE BIGTABLESPACE  
    NOLOGGING  
    NOCOMPRESS  
    NOCACHE  
    NOPARALLEL  
    MONITORING;  
    

    应该变成

    CREATE GLOBAL TEMPORARY TABLE my_table (  
      column1 NUMBER,  
      column2 NUMBER,  
      etc..  
    )  
    ON COMMIT PRESERVE ROWS;  
    

    我正在创建一个等效的全局临时表,其中的行应保留到每个现有永久表的会话结束。此全局临时表将在过程中使用,而不是永久表。
    ( EXECUTE IMMEDIATE 'TRUNCATE ...' 开始时,以及 INSERT /*+ APPEND */ INTO 在以后的某个时候)

    所有永久表都是在一个大表空间中创建的。 BIGTABLESPACE

    Oracle文档声明将在用户的临时表空间中创建全局临时表(我假设这是 TEMP )问题在于临时表空间很小,并且扩展数据块没有设置为在过程中增长到我需要的大小。

    这个 临时雇员 表空间是在数据库创建期间创建的

    create database "$oracle\_sid"  
       user sys identified by "$sys\_password"  
       user system identified by "$system\_password"  
       set default bigfile tablespace  
       controlfile   reuse  
       maxdatafiles  256  
       maxinstances  $maxinstances  
       maxlogfiles   16  
       maxlogmembers 3  
       maxloghistory 1600  
       noarchivelog  
       character set WE8MSWIN1252  
       national character set AL16UTF16  
       datafile  
          '$oracle\_home/oradata/$oracle\_sid/system01.dbf' size 512M  
       logfile  
          '$oracle\_home/oradata/$oracle\_sid/redo01.log' size 1G,  
          '$oracle\_home/oradata/$oracle\_sid/redo02.log' size 1G,  
          '$oracle\_home/oradata/$oracle\_sid/redo03.log' size 1G  
       sysaux datafile  
          '$oracle\_home/oradata/$oracle\_sid/sysaux01.dbf' size 256M  
       default temporary tablespace temp tempfile  
          '$oracle\_home/oradata/$oracle\_sid/temp01.dbf' size 5G  
       undo tablespace "UNDOTBS1" datafile  
          '$oracle\_home/oradata/$oracle\_sid/undotbs01.dbf' size 5G;  
    

    永久表(我计划替换的)最初是在表空间中创建的 大表空间

    -- 50G bigfile datafile size  
    create bigfile tablespace "BIGTABLESPACE"  
    datafile '$oracle\_home/oradata/$oracle\_sid/bts01.dbf' size 50G  
    extent management local  
    segment space management auto;  
    

    永久表索引最初是在表空间中创建的。 大表空间

    -- 20G bigfile datafile size  
    create bigfile tablespace "BIGINDXSPACE"  
    datafile '$oracle\_home/oradata/$oracle\_sid/btsindx01.dbf' size 20G  
    extent management local  
    segment space management auto;  
    
    • 是否可以使用全局临时表替换这些永久表?
    • 临时表空间在扩展临时表空间时会遇到问题。有没有办法在表空间中创建全局临时表及其索引? 大表空间 BIGINDXSPACE ?
    • 如果没有,我怎么做 临时雇员 表空间的行为就像一个大文件表空间,并实现索引/表分离?
    • 我能做两个吗 临时雇员 大文件表空间和创建索引到一个表和另一个表?

    我想使用全局临时表,但是我在过程中处理的数据量似乎超过了全局临时表的独立设计。 有什么建议吗?

    3 回复  |  直到 12 年前
        1
  •  4
  •   Justin Cave    15 年前

    将数据和索引分隔成单独的表空间并没有好处,除了可能使DBA更容易地将相似的对象分组在一起之外。长期以来一直存在这样一个误区,即将索引和数据分离对于性能是有益的——这是不正确的。

    临时对象应该(并且必须)存储在临时表空间中。您可以增加临时表空间的大小,或者为拥有这些对象的用户创建一个单独的临时表空间,如果您想将这些大型临时表分隔成单独的表空间的话。您不能(也不想)将它们存储在永久表空间中。

    不过,从架构上讲,我很好奇为什么临时表在您的系统中是必需的。如果有会话将10的GB写入临时表中,那么为了在其他地方写入数据,我可能会怀疑存在更有效的解决方案。在Oracle中,甚至很少需要临时表——在其他数据库中更常见的情况是,在这些数据库中,读者可以阻止编写器在处理数据之前需要从表中复制数据。甲骨文没有这样的限制。

        2
  •  1
  •   David Aldridge    15 年前

    我认为你的描述中没有什么让GTT不吸引人的。显然,您需要非常大的临时表空间,但总体上不会占用更多的空间,除非您大量使用表压缩(GTT中至少有10gr2不可用)。研究表空间组的使用: http://download.oracle.com/docs/cd/B19306_01/server.102/b14231/tspaces.htm#ADMIN01103

    使用表空间组(而不是单个临时表空间)可以缓解一个表空间不足以容纳排序结果的问题,特别是在具有多个分区的表上。表空间组允许一个并行操作中的并行执行服务器使用多个临时表空间。

    另外,不要忽略子查询factoring子句的使用。它们通常可以替换临时表的使用。然而,它们可能仍然需要同样多的临时存储空间,因为来自sqfc的大型结果集可能会溢出到磁盘,以避免消耗过多的内存,因此您仍然需要继续增加临时空间。它们非常方便,不必每次需要新的临时表时都部署新的数据库对象。

        3
  •  0
  •   Gary Myers    15 年前

    我查看了一个大型的全球临时表,以进行迁移练习。它起作用了,但为了调试和拒绝Hadling,我最终使用了普通的表。

    如果GTT不起作用,请考虑行级安全性/vpd(甚至视图)。 您可以从sys_context(“userenv”,“sessionid”)派生一列,并使用该列确保用户只能看到自己的数据。

    不过,想到多个会话同时处理多个千兆字节的数据集还是有点可怕。

    我相信对于通过过程使用的GTT,使用会话用户的临时表空间,而不是过程所有者的临时表空间。如果您可以作为单独的Oracle用户获得会话,那么您就有机会将文件IO分布在不同的表空间上。