首页 > Oracle > Oracle 数据库表之临时表!
2014
06-27

Oracle 数据库表之临时表!

临时表是数据库当中也充当比较重要的角色,用于保存事务或者会话期间的中间结果集,而且只对当前会话可见,无论数据提交与否,其他任何会话都看不到当前会话临时表的数据。所以临时表也不会存在阻塞的问题。

分配临时表的空间是从当前用户的临时表空间分配的,当有数据第一次插入到临时表中才会创建一个临时段,这点和现在版本的表差不多,在第一次插入后,才会为表分配段。oracle中的临时表有2种类型:一种是基于会话的临时表,这种临时表中的数据提交之前任然存在,但是在断开连接后,数据就没有了。另一种的基于事务的临时表,这种临时表的数据提交之后就消失了。下面看简单的例子

这里指定on commit preserve rows子句表示这是一个基于会话的临时表,只要当前会话一直没有断开,这个会话就可以看到临时表中的数据,其他会话始终无法查看。

这里指定on commit delete rows子句表示这是一个基于事务的临时表,当会话commit之后,数据就不存在了。下面简单的测试一下如上所说的功能

分别向这2种临时表插入了数据,但还未提交,查看2个临时表的数据,然后提交数据,再次查看临时表中的数据

由于jerry_temp_test2临时表是基于事务的,所以在commit之后就不能查看到数据了,断开连接后,临时表的数据都不能查看了

既然这里谈到了临时表,还有一个关于临时表的问题就不容忽略了,临时表的缺点就是优化器不能正常的得到真实的统计信息,这样是CBO中,可能执行计划就不正确,当然这在oracle中并不是什么困难的事情。我们可以使用动态采样和dbms_stats包来解决这个问题。不过在oracle11g版本中,如果一个表没有统计信息,oracle会默认采用动态采样,所以我们无需手动指定动态采样,除非需要指定采样的级别。

虽然动态采样能解决这样的问题,但凡是也是有一定代价的,动态采样必须在查询解析时完成,所以如果能提前手机适当的统计信息,就可以避免是硬解析的时候使用动态采样,这里就可以使用dbms_stats包了。

在使用dbms_stats包收集统计信息的时候也需要注意,需要指定GATHER_TEMP参数为true,才会收集全局临时表的统计信息,另外2种不同的临时表类型收集的结果也不一样,下面看一下例子

因为这里在收集统计信息的时候,没有指定GATHER_TEMP参数,所以临时表的统计信息被忽略

可以看到这2种不同类型的临时表收集统计信息的情况,基于会话的临时表会有正确的统计信息,但基于事务的临时表则没有,中是因为dbms_stats包将提交,这样导致基于事务的临时表就没有数据。所以使用dbms_stats包的时候一定要注意,没有基于事务的临时表,也就是创建临时表的时候,不是指定on commit delete rows参数的临时表,这样会导致收集到不正确的值。

我这里例子中使用的是收集schema的统计信息,当然也可以对单个表收集统计信息,也可以在收集统计信息的时候,手动填充统计信息,不过这种方式还是不适合基于事务的临时表。因为数据会被截断。

最后编辑:
作者:Jerry
一个积极向上的小青年,热衷于分享--Focus on DB,BI,ETL