使用临时表进行性能优化

来源:互联网 发布:windows 2012 r2 编辑:程序博客网 时间:2024/06/05 04:21

这两个月都在搞一存储过程,快要被它搞出精神病了。

主要是它执行的时间比较长,每次执行几十分钟是常有的事,几个小时也不少见。甚至乎这几天,执行了两天一夜都还不知道何时会圆满结束。等待本来就是一个痛苦的过程,而这个过程要几天几夜,那我不疯谁人疯。

这肯定是有问题的。执行时间超过1小时的都应该有问题。

后来,改进了之后,时间至多几十秒。

改进的关键在于使用了临时表。

具体来说,就是将要处理的数据,从巨大无比的表里面,先读到临时表,在执行过程中,就只从临时表中读取就好了。从处理几千万条记录的表,到至多一万条的表,资源的消耗一下子就降下来了,不可同日而语。

虽然,那个巨大表有索引,但始终比不上记录数小的表。事实上,在我看来,无论是分区、建立索引,其本质都是减少处理的数据量。建立索引,可以快速找到要处理的数据,而无须全表扫描。这跟临时表是殊途同归的,而相比之下,临时表效率更高,效果更明显。

临时表的数据准备好后,使用的次数也多,这个临时表的经济效益就越好,取得的成果就越大。至于插入数据时的一点点IO,简直不值一提。我想起在SQL SERVER中,有临时表和表对象两样东西,究竟是用临时表还是表对象?答案是,如果数据量大,应该用临时表;如果只有区区几十笔,则可以用表对象。为啥呢?因为临时表数据真的保存在物理磁盘,而表对象则存活于内存。内存不是比磁盘效率更高吗?对,但问题是,内存也宝贵的多,你将大量的临时数据保存于内存,则数据库能用的内存就少了,可能会引起它性能下降,因此得不偿失。

所以说,为了生成临时表,那一点点的磁盘IO不值一提,完全不用考虑。

创建oracle的临时表,类似地:

CREATE GLOBAL TEMPORARY TABLE TMP_TEST(    ID NUMBER ,    NAME VARCHAR2(32)) ON COMMIT PRESERVE ROWS;

创建出来之后,这个临时表就跟其他物理表一样可见,表面上看上去也没啥区别;区别在于其数据,会被自动清掉。清掉的方式有两种,取决于创建此临时表时的指定:

1)ON COMMIT DELETE ROWS
事务提交则清空

2)COMMIT PRESERVE ROWS
会话结束则清空