在linux系统下的oracle数据库里建立一个10万记录的新表(硬件:SCSI硬盘的新购买的服务器),然后对这个表执行 truncate table 表名,发现超慢,竟然花了6分多钟(执行这样的测试,是因为这个服务器执行一些truncate数据处理时,会出现连续执行几个小时一直运行的情况)。而拿这些测试表及数据到本地配置很普通的系统环境跟远程服务器一样的机器上测试,却只有0.1秒。碰到这个难题研究了很久,还是找不出原因,请各位帮忙指点下,谢谢!

解决方案 »

  1.   

    楼主给出的信息不足准确判断问题的原因,下面是我的猜测猜测楼主的Oracle版本<=9.2.0.4。导致这个问题的原因是Bug 3282805 在9.2.0.4和更早的版本中,truncate的内部机制决定了这个命令在运行的时候,会扫描整个buffer cache,dirty buffer会被写到文件中而clean buffer被会无效化。所以当buffer cache很大的时候,扫描时间就会偏长。这也解释了为什么在一台配置很普通的服务器上同样的操作只需要0.1秒。解决办法(选其一):
    1.drop并重新create该表
    2.打修复Bug 3282805 的补丁
    3.打9.2.0.5或更高版本的补丁
    4.升级到10g
      

  2.   

    另外,印象中,一些9.2早期的Oracle数据库,并发多个truncate命令时,也会发生性能问题。
      

  3.   

    v$session_wait
    看看truncate时在等什么.
      

  4.   

    还有种可能,就不属于Oracle自身的问题了。也就是说,如果你的表空间是字典管理且参数设置不当,导致了表HWM下面有很多很多小extent,truncate时回收空间就会占用很长时间,这点符合你说的几个小时(甚至几十个小时)。解决办法就是
    1.TRUNCATE TABLE XXXX REUSE STORAGE
    2.ALTER TABLE XXXX DEALLOCATE UNUSED KEEP XXXXM这样一部分一部分的回收空间
      

  5.   

    4楼有一点说错。
    不是HWM下,应该是所有属于表的extent
      

  6.   

    很感谢各位的朋友的回答
    说明一下:上述问题用的是10g,多建了几个重做日志后,truncate明显快了,但10万记录的表也还要2~3秒;而且偶尔也还会出现一次truncate占用较久时间的情况(不知道是不是业务在跑引起资源竞争的问题还是...)。
    请各位再帮忙分析指点下
      

  7.   

    请楼主分析一下,为什么建了几个重做日志以后truncate明显快了。
      

  8.   

    查看以下几个视图看看
    v$session,v$lock,v$session_event看是否有哪些等待事件