1

我正在尝试将存储过程中使用的永久表转换为全局临时表。我查看了这些永久表上的统计数据,其中一些表有数千万行数据,如果大小为千兆字节(最大 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)。这样做的问题是 TEMP 表空间很小,并且范围没有设置为增长到我需要它们在过程中增长的大小。

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;  

永久表(我打算替换)最初是在表空间中创建的BIGTABLESPACE

-- 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;  

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

-- 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;  
  • 用全局临时表替换这些永久表可行吗?
  • TEMP 表空间在扩展 TEMP 表空间时会遇到问题。有没有办法在表空间中创建全局临时表及其BIGTABLESPACE索引BIGINDXSPACE
  • 如果不是,我怎样才能使TEMP表空间表现得像一个大文件表空间并实现索引/表分离?
  • 我可以创建两个TEMP大文件表空间并在其中一个中创建索引并在另一个中创建表吗?

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

4

3 回答 3

4

将数据和索引分离到单独的表空间中没有任何好处,除了可能使 DBA 更愿意将相似的对象分组在一起之外。长期以来有一个神话,即分离索引和数据对性能有好处——这是不正确的。

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

不过,在架构上,我会很好奇为什么在您的系统中需要临时表。如果您有会话将 10 的 GB 写入临时表,然后可能再次读取这 10 的 GB 以便将数据写入其他地方,我倾向于怀疑有更有效的解决方案。在 Oracle 中甚至需要临时表都非常罕见——在其他数据库中更为常见,在这些数据库中,读者可以阻止写入者在处理表之前需要将数据从表中复制出来。Oracle 没有这样的限制。

于 2009-12-09T17:11:01.830 回答
1

我认为您的描述中没有任何内容使 GTT 没有吸引力。您显然需要非常大的临时表空间,但总体上不会消耗更多空间,除非您一直在大量使用表压缩(至少在高达 10gR2 的 GTT 中不可用)。查看表空间组的使用:http: //download.oracle.com/docs/cd/B19306_01/server.102/b14231/tspaces.htm#ADMIN01103

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

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

于 2009-12-10T09:32:09.230 回答
0

我查看了大型全局临时表以进行迁移练习。它有效,但为了调试和拒绝处理,我最终选择了普通表格。

如果 GTT 不起作用,请考虑行级安全性/VPD(甚至视图)。您可以拥有从 sys_context('USERENV','SESSIONID') 派生的列,并使用它来确保用户只能看到自己的数据。

多个会话同时处理数 GB 数据集的想法仍然有点吓人。

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

于 2009-12-09T23:18:13.730 回答