临时表空间主要用途是在数据库进行排序运算[如创建索引、order by及group by、distinct、union/intersect/minus/、sort-merge及join、analyze命令]、管理索引[如创建索 引、IMP进行数据导入]、访问视图等操作时提供临时的运算空间,当运算完成之后系统会自动清理。

当临时表空间不足时,表现为运算速度异常的慢,并且临时表空间迅速增长到最大空间(扩展的极限),并且一般不会自动清理了。

如果临时表空间没有设置为自动扩展,则临时表空间不够时事务执行将会报ora-01652 无法扩展临时段的错误,当然解决方法也很简单:1、设置临时数据文件自动扩展,或者2、增大临时表空间。

 

临时表空间的相关操作:

 

查询默认临时表空间:

 

SQL> select * from database_properties where property_name=’DEFAULT_TEMP_TABLESPACE’;

PROPERTY_NAME

——————————

PROPERTY_VALUE

——————————————————————————–

DESCRIPTION

——————————————————————————–

DEFAULT_TEMP_TABLESPACE

TEMP

Name of default temporary tablespace

 

查询临时表空间状态:

 

SQL> select tablespace_name,file_name,bytes/1024/1024 file_size,autoextensible from dba_temp_files;

TABLESPACE_NAME

——————————

FILE_NAME

——————————————————————————–

FILE_SIZE AUT

———- —

TEMP

/u01/app/Oracle/oradata/orcl/temp01.dbf

100 YES

 

扩展临时表空间:

 

方法一、增大临时文件大小:

SQL> alter database tempfile ‘/u01/app/oracle/oradata/orcl/temp01.dbf’ resize 100m;

Database altered.

方法二、将临时数据文件设为自动扩展:

SQL> alter database tempfile ‘/u01/app/oracle/oradata/orcl/temp01.dbf’ autoextend on next 5m maxsize unlimited;

Database altered.

方法三、向临时表空间中添加数据文件:

SQL> alter tablespace temp add tempfile ‘/u01/app/oracle/oradata/orcl/temp02.dbf’ size 100m;

Tablespace altered.

 

删除临时表空间的一个数据文件:

 

SQL> alter database tempfile ‘/u01/app/oracle/oradata/orcl/temp02.dbf’ drop;

Database altered.

 

删除临时表空间(彻底删除):

 

SQL> drop tablespace temp1 including contents and datafiles cascade constraints;

Tablespace dropped.

 

创建临时表空间:

 

SQL> create temporary tablespace temp1 tempfile ‘/u01/app/oracle/oradata/orcl/temp11.dbf’ size 10M;

Tablespace created.

 

更改系统的默认临时表空间:

 

SQL> alter database default temporary tablespace temp1;

Database altered.

 

所有用户的默认临时表空间都将切换为新的临时表空间:

 

SQL> select username,temporary_tablespace,default_ from dba_users;

 

USERNAME TEMPORARY_TABLESPACE

 

 

 

Oracle临时表空间主要用来做查询和存放一些缓冲区数据。临时表空间消耗的主要原因是需要对查询的中间结果进行排序。

 

重启数据库可以释放临时表空间,如果不能重启实例,而一直保持问题sql语句的执行,temp表空间会一直增长。直到耗尽硬盘空间。

 

网上有人猜测在磁盘空间的分配上,oracle使用的是贪心算法,如果上次磁盘空间消耗达到1GB,那么临时表空间就是1GB。也就是说当前临时表空间文件的大小是历史上使用临时表空间最大的大小。

 

临时表空间的主要作用:

 

索引create或rebuild

 

Order by 或 group by

 

Distinct 操作

 

Union 或 intersect 或 minus

 

Sort-merge joins

 

analyze

 


 

***************************************************************************************

 

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

 

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

 

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

 

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

 

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

 

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

 

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

 

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

 

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

 

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

 

三、要为临时表空间保留足够的硬盘空间。 网站设计,Www.Cx-Web.Com

 

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

 

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

 

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

 四、查询占用TEMP的SQL语句进行优化

SQL> select text from dba_views where view_name='SM$TS_FREE';

TEXT
--------------------------------------------------------------------------------
select tablespace_name, sum(bytes) bytes from dba_free_space  group by tables

查询谁在使用临时表空间:
select user,tablespace,blocks from v$sort_usage order by blocks;

哪个语句在使用临时表空间:
select sess.username,
sql.sql_text,  
sort.blocks
from v$session sess,
v$sqltext sql,
v$sort_usage sort
where sess.serial#=sort.session_num
and sort.sqladdr= sql.address
and sort.sqlhash = sql.hash_value
and sort.blocks >200;

或者:

Select se.username,se.sid,su.extents,su.blocks*to_number(rtrim(p.value))as    Space,tablespace,segtype,sql_text
from v$sort_usage su,v$parameter p,v$session se,v$sql s
where p.name='db_block_size' and su.session_addr=se.saddr and s.hash_value=su.sqlhash and s.address=su.sqladdr
order by se.username,se.sid;