Oracle 全局临时表

时间:2022-06-16 09:02:16

文章转自 http://turandot.iteye.com/blog/1705646


Oracle 全局临时表

 

     临时表(Tempotary table)用于保存事务或会话期间的中间结果集。临时表中保存的数据只对当前会话可见,所有会话都看不到其他会话的数据;即使当前会话已经提交了(commit)数据,别的会话也看不到它的数据。对于临时表,不存在多用户并发的问题,因为一个会话不会因为使用一个临时表而阻塞另一个会话。即使我们“锁住”了临时表,也不会妨碍其他会话使用临时表。

     

    临时表比常规表生成的redo少得多。不过由于临时表必须为其中包含的数据生成undo信息,所以也会生成一定的redo。update和delete会生成最多的undo,insert和select生成的undo最少。

 

    临时表会从当前登录用户的临时表空间分配存储空间,或者如果从一个定义者权限过程访问临时表,就会使用该过程所有者的临时表空间。全局临时表实际上是表本身的一个模板。创建临时表的动作不涉及存储空间分配,不会为此初始区段,这与常规表有所不同。对于临时表,运行时当一个会话第一次在临时表中放入数据时,才会为该会话创建一个临时段。由于每个回话会得到其自己的临时段(而不是一个现有段的一个区段),每个用户可能在不同的表空间为其看in是表分配空间。USER1的临时表空间可能设置为TEMP1,因此他的临时表会从这个表空间分配。USER2可能把TEMP2作为其临时表空间,它的临时表就会从那里分配。

 

   Oracle的临时表与其他关系数据库中的临时表类似,主要区别是:Oracle的临时表是“静态”定义的。每个数据库只创建一次临时表,而不是为数据库中的每个存储过程都创建一次。在Oracle历史表一定存在,他们作为对象放在数据字典中,但是在会话向临时表中放入数据之前,临时表看上去总是空的。由于临时表是静态定义的,所以你能创建引用临时表的视图,还可以创建存储过程只用静态SQL来引用临时表,等等。

 

    临时表可以是会话的(临时表中的数据可以跨提交存在,即提交之前仍然存在,但是断开连接后再连接时数据就没有了),也可以是基于事务的(提交之后数据就消失)。语法如下:

  • 基于会话  create global temporary table temp_table_session (...)  on commit preserve rows

         基于会话的临时表,在会话断开之前,或者通过一个delete或truncate物理地删除行之前,这些行会一直存在于这个临时表中。只有我的会话能看到这些行,即使我已经提交,其他会话也无法看到我的行。

  • 基于事务   create global temporary table temp_table_session (...)  on commit delete rows

          基于事务的临时表,我的会话提交时,临时表中的行就不见了。只需把分配给这个表的临时区段交回,这些行就会消失,在临时表的自动清除过程中不存在开销。

 

   

       临时表可以有永久表的许多属性。他们可以有触发器,检查约束,索引等。但永久表的某些特性在临时表中并不支持,这包括以下特性。

  • 不能有引用完整性约束。临时表不能作为外键的目标,也不能在临时表中定义外键。
  • 不能是IOT
  • 不能在任何类型的聚簇中
  • 不能分区
  • 不能通过ANALYZE表命令生成统计信息

        在所有数据库中,临时表的缺点之一就是优化器不能正常地得到临时表的真实统计信息。使用基于代价的优化器(CBO)时,有效的统计对于优化器的成败至关重要。