【正确答案】临时表空间是Oracle数据库的重要组成部分,尤其是对于大型的频繁操作,如创建索引、排序等都需要在临时表空间完成来减少内存的开销。当然对于查询性能要求较高的操作应尽可能地避免在磁盘上完成这些操作。
当SQL语句中使用了诸如ORDER BY、GROUP BY子句时,Oracle服务器就需要对所选取的数据进行排序,这时如果排序的数据量很大,那么内存的排序区(在PGA中)就可能装不下,所以,Oracle服务器就需要把一些中间的排序结果写到磁盘上,即临时表空间中。当用户的SQL语句中经常有大规模的多重排序而内存的排序区不够时,使用临时表空间就可以改进数据库的效率。
临时表空间可以被多个用户共享,它不能包含任何永久对象。临时表空间中的排序段是在实例启动后当有第一个排序操作时创建的,排序段在需要时可以通过分配EXTENTS来扩展并一直可以扩展到大于或等于在该实例上所运行的所有排序活动的总和。
若临时表空间占用过大,首先,要去检查是什么会话占用了临时表空间,具体占用了多少,临时段的具体类型是什么。通过查询视图GV$SORT_USAGE(GV$SORT_USAGE和GV$TEMPSEG_USAGE查询的结果是一致的)和GV$SESSION可以获取到临时表空间的占用情况和临时段的类型等信息。视图GV$SORT_USAGE中的SEGTYPE列的不同的值所代表的含义如下:
1)SORT:SQL排序使用的临时段,包括ORDER BY、GROUP BY、DISTINCT、窗口函数(WINDOW FUNCTION,如ROLLUP)、合并查询(UNION、INTERSECT、MINUS)、索引的创建(CREATE)和重建(REBUILD)、ANALYZE分析表等产生的排序。
2)DATA:临时表(GLOBAL TEMPORARY TABLE)存储数据使用的段。
3)INDEX:临时表上建的索引使用的段。
4)HASH:HASH算法,如HASH连接所使用的临时段。
5)LOB_DATA和LOB_INDEX:临时LOB使用的临时段。
根据上述的段类型,说明TEMP表空间大体可以分为4类占用:①SQL语句排序。②Hash Join占用。③临时表、临时表上的索引占用。④LOB对象占用。
在找到了哪些会话占用临时表空间过大后,分析这些会话,确保会话异常或SQL异常后,接着就可以将这些会话清理掉,如下:

最后,可以执行临时表空间的回收操作:

另外,还可以使用诊断事件来清理临时段。首先,确定TEMP表空间的TS#,如下:

然后,设置诊断事件来执行清理操作:
