您的位置:首页 > 数据库

11g中,HWM导致表大小超过_small_table_threshold,以致SQL物理读高的调优

2013-08-23 14:02 441 查看

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

      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

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的文章:

http://www.askmaclean.com/archives/11g-direct-path-read-10949-_small_table_threshold-_serial_direct_read.html

解决方法

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中运行。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: