ITPub博客

首页 > Linux操作系统 > Linux操作系统 > Oracle临时表和临时表空间组

Oracle临时表和临时表空间组

原创 Linux操作系统 作者:sxrenjb 时间:2012-05-30 15:11:14 0 删除 编辑

一、临时表功能介绍:

    Oracle中的临时表是全局的,需要在数据库设计时创建完成,而不是程序使用时。每个登陆用户都使用这一个相同的临时表,但互相之间看不到彼此的数据,也就是说临时表是会话独立的。并且不产生日志。

    Oracle 的临时表分为事务型和会话型。

    事务型临时表就是指在事务处理过程中插入的记录只在事务提交或回滚之前有效,一旦事务完成,表中的记录便被自动清除。

    会话型临时表指临时表中的数据在本次会话期间一直有效,直到会话结束。会话结束后表中针对此次会话的数据会自动清空。

Oracle 临时表的不足之处:

1、不支持lob对象,例如 Spatial SDO_GEOMETRY。这也许是设计者基于运行效率的考虑,但实际应用中确实需要此功能时就无法使用临时表了。

2、不支持主外键关系。这意味着临时表 

创建临时表的语法:

CREATE GLOBAL TEMPORARY TABLE table

"(" column datatype [DEFAULT expr] [{ NULL | NOT NULL}] 

[, column datatype [DEFAULT expr] [ {NULL | NOT NULL} ]... ")"

ON COMMIT {DELETE | PRESERVE } ROWS ;

--Sample

CREATE GLOBAL TEMPORARY TABLE TABLE_NAME (

   COL1  VARCHAR2(10),

   COL2  NUMBER

) ON COMMIT PRESERVE(DELETE) ROWS ;

如果选择PRESERVE ROWS,则在会话结束后表中的数据自动清空,如果选了DELETE ROWS,则在提交的时候即清空数据,PRESERVE则一直到会话结束。

    Oracle中的临时表有两种一种是事务级别的临时表它在事务结束的时候自动清空记录,另一种是会话级的它在我们访问数据库时的一个会话结束后自动的清空。关于临时表多用户并行不是问题,一个会话从来不会阻止另一个会话使用临时表。即使“锁定”临时表,一个会话也不会阻止其他会话使用它们的临时表。

    如果有在SQL SERVER \sybase中使用临时表的经验,需要主要考虑的不是执行select xy ,z into #temp from some_table 来创建和装载临时表,而是:

 

1.对于每一个数据库,创建所有的temp表作为全局临时表。这将作为应用程序安装的一部分完成,就像创建永久表一样。

 

2.只要在过程中简单的insert into temp(x,y,z) selelct x,y,z from some_table

 

只是理解这点,这里的目的不是运行存储过程创建表。在Oracle中这样做不是正确的方法。DDL是一种消耗资源非常大的操作,在运行时尽量不要使用,应用程序需要的临时表应在应用程序安装时创建,而不是在运行时创建。Oracle中的临时表和其他数据库的临时表是相似的,在每个数据库中创建临时表一次,不必在数据库中的每个存储过程中创建一次。临时表总是存在的,他们作为对象存在于数据字典中,并且总是保持为空,直到有会话在其中放入数据。

 

所有我在这里说明如果我们在存储过程中建临时表,每次都建立一个那么我的系统随着用户的操作调用此存储过程,每次多一个这样的表,我们在不知不觉中数据库中的表的数量会越来越多,而我们还不知道会存在很大的隐患的所有说这点不可小视,为了我们的系统能在客户那里平稳、安全的运行我们一定要注意这样的问题。如果不手动Drop 表,临时表还是在数据字典中存在的。 

二、临时表空间组介绍

Temporary Tablespace Groups 

Oracle Database 10g introduced the concept of a temporary tablespace group. Rather than having just one temporary tablespace and the possibility that it may become a performance bottleneck, you can define an entire group of temporary tablespaces and spread temporary tablespace input/output across them. To create a group of temporary tablespaces, simply specify the GROUP clause when creating it. Both of the following tablespaces comprise a temporary tablespace group named temp_group01: 

CREATE TEMPORARY TABLESPACE temp01 TEMPFILE '/oradata/db01/

temp01.dbf' SIZE 100M

EXTENT MANAGEMENT LOCAL UNIFORM SIZE 16M TABLESPACE GROUP temp_group01;

CREATE TEMPORARY TABLESPACE temp02 TEMPFILE '/oradata/db02/

temp02.dbf' SIZE 100M

EXTENT MANAGEMENT LOCAL UNIFORM SIZE 16M TABLESPACE GROUP temp_group01;

Having created a group of temporary tablespaces, you can now make that group the default source of temporary disk space for your database, as follows: 

ALTER DATABASE DEFAULT TEMPORARY TABLESPACE temp_group01;

Now, rather than have all temporary input/output go against a single temporary tablespace, the database can distribute that I/O load among all the temporary tablespaces in the group. Temporary tablespace groups are even more of an advantage when you are performing operations in parallel. If you issue an ORDER BY query against a partitioned table and if multiple execution server processes are started in order to process that query in parallel, one for each partition, those execution servers no longer need to all funnel to the same temporary tablespace. Instead, the execution servers will be distributed across all the temporary tablespaces in the active group.

    在 oracle 10g ,可以创建多个临时表空间,并把它们组成一个临时表空间组,这样应用

数据用于排序时可以使用组里的多个临时表空间,一个临时表空间组至少有一个临时表空

,其最大个数没有限制,组的名字不能和其中某个表空间的名字相同。

     临时表空间组是在创建临时表空间时通过指定group字句创建的,如果删除组中的全部

临时表空间,那么这个组也将消失。 

    我们将可以将一个表空间从一个组移动另一个组,或是从一个组中删除临时表空间,或是往组里添加新的表空间。

    使用临时表空间组,有如下的优点:    

    1.避免当临时表空间不足时所引起的磁盘排序问题;    

    2.当一个用户同时有多个会话时,可以使得它们使用不同的临时表空间;

    3.使得并行的服务器在单节点上,能使用多个临时表空间 .

现在就看看如何操作使用临时表空间组:

1:创建临时表空间组:

     SQL> create temporary tablespace tempts1 tempfile

          2  '/home/oracle/temp1_02.dbf' size 2M tablespace group group1;

     Tablespace created

                  

     SQL> create temporary tablespace tempts2 tempfile

          2  '/home/oracle/temp2_02.dbf' size 2M tablespace group group2;

     Tablespace created

2.查询临时表空间组:   SQL> select * from dba_tablespace_groups;

GROUP_NAME                     TABLESPACE_NAME

------------------------------ ------------------------------

GROUP1                         TEMPTS1

GROUP2                         TEMPTS2

3.将表空间从一个临时表空间组移动到另外一个临时表空间组:  

SQL> alter tablespace tempts1 tablespace group GROUP2 ;

Tablespace altered

SQL> select * from dba_tablespace_groups;

GROUP_NAME                     TABLESPACE_NAME

------------------------------ ------------------------------

GROUP2                         TEMPTS1

GROUP2                         TEMPTS2

4.把临时表空间组指定给用户 

SQL>  alter user scott temporary tablespace GROUP2;

User altered

5.在数据库级设置临时表空间 

SQL>  alter database  default temporary tablespace GROUP2;  

Database altered. 

6. 删除临时表空间组 (删除组成临时表空间组的所有临时表空间

SQL> drop tablespace tempts1 including contents and datafiles;

Tablespace dropped

SQL>  select * from dba_tablespace_groups;

GROUP_NAME                     TABLESPACE_NAME

------------------------------ ------------------------------

GROUP2                         TEMPTS2

SQL> drop tablespace tempts2 including contents and datafiles;

Tablespace dropped

SQL>  select * from dba_tablespace_groups;

GROUP_NAME                     TABLESPACE_NAME

------------------------------ ------------------------------

 

7、对全局临时表的总结

在临时表上的操作比在一般的表上的操作要快。因为:  
  1)创建临时表不需要往编目表中插入条目,临时表的使用也不需要访问编目表,因此也没有对编目表的争用。  
  2)仅有创建临时表的app才可存取临时表,所以在处理临时表时没有锁。  
  3)如果指定NOT   LOGGED选项,在处理临时表时不记日志。所以如果有仅在数据库的一个会话中使用的大量临时数据,把这些数据存入临时表能大大提高性能。

 

在Oracle中,全局临时表并不会删除,实际上你只需要建立一次,以后直接应用就行了,这与MS和Sybase不一样。实际上在断开数据库连接时,临时表中数据自动清空,不同的Session之间是隔离的,不许要当心相互影响,不过如果起用了连接共享的话,你要用On   Commit   delete   rows使数据仅在事物内部有效。

 

二、不要让临时表空间影响数据库性能

Oracle数据库中进行排序、分组汇总、索引等到作时,会产生很多的临时数据。如有一张员工信息表,数据库中是安装记录建立的时间来保存的。如果用户查询时,使用Order BY排序语句指定按员工编号来排序,那么排序后产生的所有记录就是临时数据。对于这些临时数据,Oracle数据库是如何处理的呢?

  通常情况下,Oracle数据库会先将这些临时数据存放到内存的PGA(程序全局区)内。在这个程序全局区中有一个叫做排序区的地方,专门用来存放这些因为排序操作而产生的临时数据。但是这个分区的容量是有限的。当这个分区的大小不足以容纳排序后所产生的记录时,数据库系统就会将临时数据存放到临时表空间中。这就是临时表空间的来历。看起来好像这个临时表空间是个临时工,对于数据库的影响不会有多大。其实大家这是误解这个临时表空间了。在用户进行数据库操作时,排序、分组汇总、索引这些作业是少不了,其会产生大量的临时数据。为此基本上每个数据库都需要用到临时表空间。而如果这个临时表空间设置不当的话,则会给数据库性能带来很大的负面影响。为此管理员在维护这个临时表空间的时候,不能够掉以轻心。要避免因为临时表空间设置不当影响数据库的性能。具体来说,主要需要注意如下几个方面的内容。

  1)、创建用户时要记得为用户创建临时表空间。

  最好在创建用户时为用户指定临时表空间。如可以利用语句default temporary table space语句来为数据库设置默认的临时表空间。不过在Oracle数据库中这个不是强制的。但是笔者强烈建议这么做。因为如果没有为用户指定默认临时表空间的话,那么当这个用户因为排序等操作需要使用到临时表空间的话,数据库系统就会“自作聪明”的利用系统表空间SYSTEM来创建临时段。众所周知,这是一个系统表空间。由于在这个表空间中存放着系统运行相关的数据,一般的建议是用户的数据不能够保存在这个表空间中。那么如果将用户的临时表空间防止在这个系统表空间之内,会产生什么负面影响呢?

由于临时表空间中的数据是临时的。为此数据库系统需要频繁的分配和释放临时段。这些频繁的操作会在系统表空间中产生大量的存储碎片。当这些存储碎片比较多时,就会影响系统读取硬盘的效率,从而影响数据库的性能。其次系统表空间的大小往往是有限制的。此时临时段也来插一脚,就会占用系统表空间的大小。

  为此数据库管理员需要注意一点,当没有为用户指定临时表空间时,用户排序等操作仍然需要用到临时段。此时数据库系统就会将临时段放入到系统表空间中。为此就会对数据库的性能产生不利的影响。所以笔者建议各位读者与数据库管理员,在创建用户的时候同时为用户指定一个默认的表空间,以减少临时段对系统表空间的占用。

  2)、合理设置PGA,减少临时表空间使用的几率。

  当排序操作产生临时数据时,数据库并不是马上将其存储在临时表空间中。通常情况下,会先将这些临时数据存储在内存的PGA程序全局区内。只有当这个程序全局区无法容纳全部数据时,数据库系统才会启用临时表空间中的临时段来保存这些数据。但是众所周知,操作系统从内存中读取数据要比从硬盘中读取数据块几千倍。为此比较理想的情况是,这个程序全局区足够的大,可以容纳所有的临时数据。此时数据库系统就永远用不到临时表空间了。从而可以提高数据库的性能。

  但是这毕竟只是一个理想。由于内存大小等多方面的限制,这个PGA程序区的大小往往是有限制的。所以在进行一些大型的排序操作时,这个临时表空间仍然少不了。现在数据库管理员可以做的就是合理设置这个PGA程序全局区的大小,尽量减少临时表空间使用的几率。如在实际工作中,数据库管理员可以根据需要来设置初始化参数SORT_AREA_SIZE参数。这个参数主要控制这个PGA程序全局区内排序区的大小。通常情况下,如果这个数据库系统主要用来查询并且需要大量的排序、分组汇总、索引等操作时,那么可以适当调整这个参数,来扩大PGA分区的大小。相反,如果这个系统主要用于更新操作,或者在这个数据库服务器上还部署由其他的应用程序,那么这个PGA分区就不能够占用太多的内存,以防止对其他应用程序产生不利的影响。所以说,数据库官员不能够一刀切,需要根据实际情况来调整。在必要的情况下,可以增加系统内存来增加PGA分区的大小,从而降低临时表空间的使用几率,以提高数据库的排序、分组汇总等操作的性能。

 总之,如果临时段被频繁使用的话,由于内存硬盘在性能上的差异,从而会降低数据库的性能。为此在平时工作中,数据库管理员还需要监控临时表空间的使用情况,以判断是否需要采取措施来减少临时表空间的使用来提高数据库的查询性能。为了实现这个目的,笔者建议数据库管理员可以查看v$sort_segment这张动态性能视图。通过这张动态性能视图可以查看系统排序段(临时段的一种)的使用情况。另外通过动态性能视图v$sort_usage还可以查询使用排序段的用户与会话信息。从而为数据库管理员优化数据库性能提供数据上的支持。对于这个排序段,笔者还要说明一点。对于排序段来说,同一个例程的所有SQL语句(如果需要排序操作的话)都将共享同一个排序段。并且排序段在第一次需要用到时被创建。排序完成后这个排序段不会被释放,只有在这个历程关闭后排序段才会被释放。为此以上两张视图要综合起来分析,才能够得到数据库管理员想要的信息。

  3)、要为临时表空间保留足够的硬盘空间。

  其他表空间对应的数据文件,在其创建时就会被完全分配和初始化,即在其创建时就会被分配存储空间。但是临时表空间对应的临时文件则不同。如在Linux操作系统中,临时表空间创建时系统是不会分配和初始化临时文件的。也就是说,不会为临时文件分配存储空间。只有临时数据出现需要用到临时文件的时候,系统才会在硬盘上分配一块地方用来保存临时文件。此时就可能会产生一个问题,即当需要用到临时文件系统为其分配空间的时候,才会先系统分区中没有足够的存储空间了。此时就会产生一些难以预料的后果。

  为此对于这些临时文件,数据库管理员最好能够预先为其保留足够的空间。如在Linux操作系统中,可以将其防止在一个独立的分区内,不允许其他应用程序使用。如此的话,就不用担心临时文件没有地方存储了。另外由于临时表空间主要用来存放一些排序用的临时文件。为此如果能够将这个临时表空间存放在性能比较好的分区中,还可以提高数据库系统读取临时表空间中数据的速度。另外由于系统需要频繁分配临时表空间中的数据,为此临时表空间所在的分区会出现比较多的碎片。此时如果将临时表空间存放在一个独立的分区内,那么数据库管理员就可以单独对这个分区进行碎片整理,从而提高这个分区的性能。所以无论出于什么原因,将临时表空间防止在一个独立的分区内,是一个不错的想法。不仅可以保证临时文件有存储的空间,而且还可以提高数据库的性能。

  对于临时表空间最后需要说明的是,默认情况下这个临时表空间对各个用户都是共享的。也就是说每个连接到数据库的用户都可以使用默认的临时表空间。数据库管理员可以为其指定其他的临时表空间。一般来说,只需要一个临时表空间即可。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/11949963/viewspace-731472/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2012-05-16

  • 博文量
    26
  • 访问量
    29804