现在我们大致了解了这条系统SQL产生的几个原因,排除了BUG因素,我们需要检查:
1.alert日志,对应时间段是否有alter tablespace操作,例如add datafile。 <== NO
2.查看AWR,是否存在许多insert,造成需要扩充段空间(add extent)。 <== yes
3.检查是否有数据文件为autoextend。 <== no
TOPSQL中确实有几条INSERT,并且据客户介绍这个系统是OLAP系统,在繁忙时间段有很多抽数操作,需要将其他系统的数据抽进来,插入到 数据库中,
因此比较符合第2点推测,如下:
SQL ordered by Gets
Buffer Gets Executions Gets per Exec %Total CPU Time (s) Elapsed Time (s) SQL Id SQL Module SQL Text
...
13,996,731 109,095 128.30 3.80 586.11 1708.30 b2cfm5jm9888j GP4MSOX3DWK74QT9KQ0S2LNJLU0 INSERT INTO "/BIC/AMM00_O2900"...
10,222,371 126,034 81.11 2.77 494.23 1396.76 fqwvuf7w3kk7d GP4NBPK14Z49C1BR3I63Q5TQY4O INSERT INTO "/BIC/B0003586000"...
9,017,859 471 19,146.20 2.45 33.79 178.54 5xxbw9gqqugr7 CL_RSBC_FILTER_CMD============CP INSERT INTO "D010TAB" ( "MASTE...
...
以上平均每条insert的逻辑读在100次以上,推测是在执行insert的时候需要为表段分配新的分区(extent),导致了SQL bsa0wjtftg3uw的执行,带来了额外的逻辑读。
口说无凭,实验说明一切,做了个简单测试:
1. Create a new table t2 and try insert some data. Note: there are any extents allocation occurs in the session
====================
SQL> create table t2 as select * from dba_objects where 1=2;
SQL> select count(*) from dba_extents where owner='EDISON' and segment_name='T2';
COUNT(*)
----------
1
SQL> alter session set timed_statistics = true;
Session altered.
SQL> alter session set statistics_level=all;
Session altered.
SQL> alter session set max_dump_file_size = unlimited;
Session altered.
SQL> alter session set events '10046 trace name context forever, level 12';
Session altered.
SQL> insert into t2 select * from dba_objects;
51268 rows created.
SQL> insert into t2 select * from t2;
51268 rows created.
SQL> /
102536 rows created.
SQL> alter session set events '10046 trace name context off';
Session altered.
SQL> select count(*) from dba_extents where owner='EDISON' and segment_name='T2'; <===分配了38个extent
COUNT(*)
----------
38
检查trc文件:
select file# from file$ where ts#=:1 <===执行了72次
call count cpu elapsed disk query current rows
Parse 72 0.00 0.01 0 0 0 0
Execute 72 0.00 0.00 0 0 0 0
Fetch 144 0.00 0.00 0 288 0 72
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 288 0.00 0.01 0 288 0 72
2. 删除所有数据,但不回收EXTENT
====================
SQL> delete from t2;
205072 rows deleted.
SQL> commit;
Commit complete.
SQL> select count(*) from dba_extents where owner='EDISON' and segment_name='T2';
COUNT(*)
----------
38
SQL> alter session set timed_statistics = true;
Session altered.
SQL> alter session set statistics_level=all;
Session altered.
SQL> alter session set max_dump_file_size = unlimited;
Session altered.
SQL> alter session set events '10046 trace name context forever, level 12';
Session altered.
SQL> insert into t2 select * from dba_objects;
51268 rows created.
SQL> insert into t2 select * from t2;
51268 rows created.
SQL> commit;
Commit complete.
SQL> alter session set events '10046 trace name context off';
Session altered.
SQL> select count(*) from dba_extents where owner='EDISON' and segment_name='T2';
COUNT(*)
----------
38
检查trc文件,未发现有select file# from file$ where ts#=:1 执行。
解决方法:
1.将表的NEXT属性调大避免多次分配extent。
ALTER TABLE T2 STORAGE(NEXT NM);
2.手动为表分配extent
ALTER TABLE T2 ALLOCATE EXTENT ALLOCATE EXTENT (SIZE NM);