ORACLEl数据库truncate分区表很慢问题
Apr132016
在测试环境TRUNCATE一张按天分区的大表,数据量大概30G,速度非常慢,大概需要半个小时,检查发现等待的是log file switch事件。本案例数据库版本为11.2.0.4.0,操作系统为OEL 6.5。
SQL> select sql_id,OSUSER,MACHINE,TERMINAL,PROGRAM,EVENT,STATE from v$session where username='CHGSHS'; SQL_ID EVENT STATE ------------- ---------------------------------------- ---------- 74jc7bvw5p1fg log file switch (checkpoint incomplete) WAITING SQL> select SQL_TEXT from v$sqltext where sql_id='74jc7bvw5p1fg'; SQL_TEXT ---------------------------------------------------------------- truncate table ORD_ORD_BSC_M
过一会再次查询,等待事件变成了local write wait。
SQL> select sql_id,OSUSER,MACHINE,TERMINAL,PROGRAM,EVENT,STATE from v$session where username='CHGSHS'; SQL_ID EVENT STATE ------------- ---------------------------------------- ---------- 74jc7bvw5p1fg local write wait WAITING
过一会又变成了enq: RO – fast object reuse。
SQL_ID EVENT STATE ------------- ---------------------------------------- ---------- 74jc7bvw5p1fg enq: RO - fast object reuse WAITING
这是因为在truncate表时,要把内存中缓存的数据先写入到磁盘中,local write wait和enq: RO – fast object reuse等待事件基本都是因为磁盘写速度不够导致的,通常在truncate或者drop table purge大表特别是分区很多的表时会出现。
我在truncate这张表的时候,数据库还在加载这数据,日志切换发生了很严重的等待。
SQL> select * from v$log; GROUP# THREAD# SEQUENCE# BYTES STATUS ---------- ---------- ---------- ---------- -------- 1 1 1005 1073741824 ACTIVE 2 1 1006 1073741824 ACTIVE 3 1 1011 1073741824 ACTIVE 4 1 1012 1073741824 ACTIVE 5 1 1007 1073741824 ACTIVE 6 1 1008 1073741824 ACTIVE 7 1 1009 1073741824 ACTIVE 8 1 1010 1073741824 ACTIVE 9 1 1013 1073741824 CURRENT 9 rows selected.
所以上面遇到的log file switch等待事件就很正常了,分析发现数据库的数据写进程(db write)过少,内存中的数据写入磁盘速度太慢导致的。
针对这个问题,最好的解决方法是增加数据写进程的数量,这是个静态参数,需要重启数据库才能生效,如果当前数据库无法重启,可以选择将表先删除到回收站,然后再创建表的方式来代替truncate,drop table purge的方式也会触发内存中的数据写入磁盘,使用purge的方式删除大表特别是分区较多的表时,也会很慢,但是将表删除到回收站则不会触发这些动作,会很快完成。