我正在尝试将存储过程中使用的永久表转换为全局临时表。我查看了这些永久表上的统计数据,有些数据库有数千万行数据,如果是千兆字节(最多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;
BIGTABLESPACE
和BIGINDXSPACE
中创建全局临时表及其索引?TEMP
表空间像bigfile表空间一样运行并实现索引/表分离?TEMP
bigfile表空间并将索引创建为一个,将表创建到另一个表中吗?我想使用全局临时表,但我在过程中处理的数据量似乎超出了全局临时表的indended设计。 有什么建议吗?
答案 0 :(得分:4)
将数据和索引分离到单独的表空间没有任何好处,除了可能使DBA更容易将类似对象组合在一起。长期以来的一个神话是,分离索引和数据对于性能原因是有益的 - 这是不正确的。
临时对象应该(并且必须)存储在临时表空间中。如果要将这些大型临时表隔离到单独的表空间中,可以增加TEMP表空间的大小或为拥有这些对象的用户创建单独的临时表空间。您不能(也不希望)将它们存储在永久表空间中。
但在架构上,我会非常好奇为什么系统中需要临时表。如果你有10个GB的会话写入临时表,那么为了将数据写入其他地方,可能会再次读取那10个GB,我倾向于怀疑有更高效的解决方案。在Oracle中甚至需要临时表是非常罕见的 - 在其他数据库中更为常见,在这些数据库中,读者可以阻止编写者在处理数据之前将数据复制出表。 Oracle没有这样的限制。
答案 1 :(得分:1)
我不认为你的描述中有任何东西会让GTT变得没有吸引力。您显然需要非常大的临时表空间,但除非您大量使用表压缩(GTT中至少不能达到10gR2),否则您不会消耗更多的空间。查看表空间组的使用:http://download.oracle.com/docs/cd/B19306_01/server.102/b14231/tspaces.htm#ADMIN01103
使用表空间组而不是单个临时表空间可以缓解由于一个表空间不足以保存排序结果而导致的问题,尤其是在具有多个分区的表上。表空间组使并行执行服务器在单个并行操作中使用多个临时表空间。
另外,不要忽视子查询因子条款的使用。他们经常可以替换临时表的使用。但是,它们可能仍然需要同样多的临时存储空间,因为来自SQFC的大量结果集可以溢出到磁盘以避免消耗太多内存,因此您仍然需要继续增加TEMP空间。它们非常便于每次需要新的临时表时不必部署新的数据库对象。
答案 2 :(得分:0)
我查看了大型全球临时表以进行迁移练习。它起作用但是为了调试和拒绝hadling我最终使用普通表。
如果GTT无法解决,请考虑行级安全性/ VPD(甚至视图)。 您可以拥有一个派生自sys_context('USERENV','SESSIONID')的列,并使用它来确保用户只能看到自己的数据。
同时处理多千兆字节数据集的多个会话的想法仍然有点可怕。
PS。我相信对于通过过程使用的GTT,使用会话用户的临时表空间而不是过程所有者的临时表空间。如果您可以将会话作为单独的oracle用户进行,那么您有可能将文件IO分散到不同的表空间。