SQL问题描述:
有1个SQL,在10g中,执行计划无物理读,11g,物理读高,始终存在,SQL如下:
select t.id id, t.state state
from PUSH t
where t.row_ID = '20130131036383'
and t.cal_ID = '51bb2b9371974004467b2d26'
and t.calType = 'M'
and t.modelID = '20130814934325'
and t.phaseID = '51bb2b9371974004467b2d26'
and t.groupID = '33005'
and t.subjectID = '0'
and t.allGroup = '0'
and t.allSubject = '1'
and t.allType = '0'
and t.allPhase = '0';
10g中的执行计划:
Elapsed: 00:00:01.43
Execution Plan
----------------------------------------------------------
Plan hash value: 2553857029
--------------------------------------------------------------------------------
---------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| T
ime |
--------------------------------------------------------------------------------
---------
| 0| SELECT STATEMENT | | 1 | 126 | 10254 (1)| 0
0:02:04 |
|* 1| TABLE ACCESS FULL| PUSH | 1 | 126 | 10254 (1)| 0
0:02:04 |
--------------------------------------------------------------------------------
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
14431 consistent gets
0 redo size
304 bytes sent via SQL*Net toclient
465 bytes received via SQL*Netfrom client
1 SQL*Net roundtrips to/fromclient
0 sorts (memory)
0 sorts (disk)
0 rows processed
11g的执行计划:
Elapsed: 00:00:01.43
Execution Plan
----------------------------------------------------------
Plan hash value: 2553857029
--------------------------------------------------------------------------------
---------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| T
ime |
--------------------------------------------------------------------------------
---------
| 0| SELECT STATEMENT | | 1 | 126 | 10254 (1)| 0
0:02:04 |
|* 1| TABLE ACCESS FULL| PUSH | 1 | 126 | 10254 (1)| 0
0:02:04 |
--------------------------------------------------------------------------------
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
14431 consistent gets
14330 physical reads
0 redo size
304 bytes sent via SQL*Net toclient
465 bytes received via SQL*Netfrom client
1 SQL*Net roundtrips to/fromclient
0 sorts (memory)
0 sorts (disk)
0 rows processed
问题原因及相应解决办法
1. 11g版本新特性:
原因
11g direct path read,_small_table_threshold与_serial_direct_read。
当表大小超过_small_table_threshold(隐藏参数的值在实例启动时动态决定,一般为 2% * DB_CACHE_SIZE。)时,执行计划会走direct path read。
关于此特性,参见ML的文章:
解决方法
SQL> alter session set"_small_table_threshold"=999999;
会话已更改。
SQL> set timing on;
SQL> set autot on;
SQL> select t.id id, t.state state
2 from PUSH t
3 where t.row_ID ='20130131036383'
4 and t.cal_ID ='51bb2b9371974004467b2d26'
5 and t.calType = 'M'
6 and t.modelID ='20130814934325'
7 and t.phaseID ='51bb2b9371974004467b2d26'
8 and t.groupID = '33005'
9 and t.subjectID = '0'
10 and t.allGroup = '0'
11 and t.allSubject = '1'
12 and t.allType = '0'
13 and t.allPhase = '0';
未选定行
已用时间: 00: 00: 00.03
执行计划
----------------------------------------------------------
Plan hash value: 2553857029
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0| SELECT STATEMENT | | 1 | 111 | 10254 (1)| 00:02:04 |
|* 1| TABLE ACCESS FULL| PUSH | 1 | 111 | 10254 (1)| 00:02:04 |
-----------------------------------------------------------------------------------------
Predicate Information (identified byoperation id):
---------------------------------------------------
1- filter("T"."SUBJECTID"='0' AND"T"."CAL_ID"='51bb2b9371974004467b2d26'
AND"T"."PHASEID"='51bb2b9371974004467b2d26' AND"T"."ROW_ID"='20130131036383'
AND"T"."MODELID"='20130814934325' AND"T"."CALTYPE"='M' AND
"T"."GROUPID"='33005' AND"T"."ALLGROUP"='0' AND"T"."ALLSUBJECT"='1' AND
"T"."ALLTYPE"='0'AND "T"."ALLPHASE"='0')
Note
-----
-'PLAN_TABLE' is old version
统计信息
----------------------------------------------------------
0 recursive calls
0 db block gets
14431 consistent gets
0 physical reads
0 redo size
304 bytes sent via SQL*Net toclient
348 bytes received via SQL*Netfrom client
1 SQL*Net roundtrips to/fromclient
0 sorts (memory)
0 sorts (disk)
0 rows processed
2. 高水位导致表过大:
原因
SQL> select num_rows,blocks,empty_blocks from dba_tables
where table_name='PUSH';
NUM_ROWS BLOCKS EMPTY_BLOCKS
---------- ---------- ------------
3485 37784 104
SQL> select segment_name,blocks,bytesfrom dba_segments where segment_name='PUSH'
2 ;
SEGMENT_NAME
------------------------------------------------------------------------------
BLOCKS BYTES
---------- ----------
PUSH
37888 310378496
该表只有3485行,但是37784的高水位,导致该表大小大约300M,远大于_small_table_threshold(0.02*2G),所以在11g中就走了directpath read,最后有了 14330 physical reads
解决的办法就是降低高水位,降低该表大小。
解决方法
采用了重建的办法,尝试解决该问题
create table PUSHbak as select * from PUSH;
效果:
已用时间: 00: 00: 00.01
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0| SELECT STATEMENT | | 1 | 124 | 17 (0)| 00:00:01 |
|* 1| TABLE ACCESS FULL| PUSH | 1 | 124 | 17 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
188 recursive calls
0 db block gets
89 consistent gets
0 physical reads
0 redo size
323 bytes sent via SQL*Net toclient
389 bytes received via SQL*Netfrom client
1 SQL*Net roundtrips to/fromclient
4 sorts (memory)
0 sorts (disk)
下面再看表的大小,和高水位
SQL> select num_rows,blocks,empty_blocksfrom dba_tables where table_name='PUSHBAK';
NUM_ROWS BLOCKS EMPTY_BLOCKS
---------- ---------- ------------
3485 71 0
SQL> select segment_name,bytes fromdba_segments where segment_name='PUSHBAK'
2 ;
SEGMENT_NAME BYTES
------------------------------------------------------------------------------------------
PUSHBAK 589824
高水位由37784 降到71,大小由310378496降到589824。此时的大小,可以完全在buffer cache中运行。