optimizer_index_cost_adj和optimizer_index_caching對CBO的影響

myownstars發表於2012-07-25

DB10205

OS:  HP UX B.11.11

目的:

測試optimizer_index_cost_adjoptimizer_index_cachingCBO生成執行計劃的影響,前者的取值範圍0-10000,預設為100;後者則為0-100,預設為0

關於這兩個引數的資料比較少,只找到如下一些;

oracle高效設計》大致記錄如下:optimizer_index_caching告訴資料庫buffer cache中索引塊的百分比,值越高則意味cache中的索引塊數越多,其相應的io cost越小,optimizer_index_cost_adj則相反;

由馮大輝等人翻譯的《oracle效能診斷藝術》則有著更詳細的描述,書中提供了兩個計算索引io代價公式

io_cost = (blevel + (leaf_blocks + clustering_factor) * selectivity) * optimizer_index_cost_adj/100

io_cost = {(blevel + leaf_blocks*selectivity) * (1 – optimizer_index_caching/100) + clustering_factor * selectivity} * (optimizer_index_cost_adj/100)

很直觀的描述了兩個引數對CBO的影響,且optimizer_index_cost_adjCBO的影響非常大,而optimizer_index_caching則相對小很多

 

下面做試驗測試一下

設定三組測試案例,引數分別設定為

1 optimizer_index_cost_adj            =100optimizer_index_caching             =0

2 optimizer_index_cost_adj            =10optimizer_index_caching             =0

3 optimizer_index_cost_adj            =10 optimizer_index_caching             =100

 

建立測試表

SQL> create table tmp_t as select object_id,owner from dba_objects;

 

Table created.

SQL> select count(*) from tmp_t;

 

  COUNT(*)

----------

     41187

SQL> select count(*) from tmp_t where wner='PUBLIC';

 

  COUNT(*)

----------

     16036

SQL> create index tmp_index on tmp_t(owner);

 

Index created.

SQL> exec dbms_stats.gather_table_stats('SYS','TMP_T',estimate_percent => 100);

 

PL/SQL procedure successfully completed.

 

設定10053跟蹤

1

optimizer_index_cost_adj            = 100

optimizer_index_caching             = 0

 

SQL> alter session set events '10053 trace name context forever, level 12';

 

Session altered.

 

SQL> set autotrace traceonly

SQL> select * from tmp_t where wner='PUBLIC';

 

16036 rows selected.

 

 

Execution Plan

----------------------------------------------------------

Plan hash value: 1035233137

 

---------------------------------------------------------------------------

| Id  | Operation         | Name  | Rows  | Bytes | Cost (%CPU)| Time     |

---------------------------------------------------------------------------

|   0 | SELECT STATEMENT  |       | 16036 |   187K|    23  (14)| 00:00:01 |

|*  1 |  TABLE ACCESS FULL| TMP_T | 16036 |   187K|    23  (14)| 00:00:01 |

---------------------------------------------------------------------------

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   1 - filter("OWNER"='PUBLIC')

 

 

Statistics

----------------------------------------------------------

          0  recursive calls

          0  db block gets

       1121  consistent gets

          0  physical reads

          0  redo size

     354186  bytes sent via SQL*Net to client

      12251  bytes received via SQL*Net from client

       1071  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

      16036  rows processed

 

SQL> alter session set events '10053 trace name context off';

 

Session altered.

跟蹤檔案

SYSTEM STATISTICS INFORMATION

*****************************

  Using NOWORKLOAD Stats—使用的非工作量統計資訊

  CPUSPEED: 199 millions instruction/sec

  IOTFRSPEED: 4096 bytes per millisecond (default is 4096)

  IOSEEKTIM: 10 milliseconds (default is 10)

***************************************

BASE STATISTICAL INFORMATION

***********************

Table Stats::

  Table: TMP_T  Alias: TMP_T

    #Rows: 41187  #Blks:  49  AvgRowLen:  12.00

Index Stats::

  Index: TMP_INDEX  Col#: 2

    LVLS: 1  #LB: 52  #DK: 57  LB/K: 1.00  DB/K: 5.00  CLUF: 290.00

***************************************

SINGLE TABLE ACCESS PATH

  -----------------------------------------

  BEGIN Single Table Cardinality Estimation

  -----------------------------------------

  Column (#2): OWNER(VARCHAR2)

    AvgLen: 8.00 NDV: 57 Nulls: 0 Density: 1.2140e-05

    Histogram: Freq  #Bkts: 57  UncompBkts: 41187  EndPtVals: 57

  Table: TMP_T  Alias: TMP_T    

    Card: Original: 41187  Rounded: 16036  Computed: 16036.00  Non Adjusted: 16036.00

  -----------------------------------------

  END   Single Table Cardinality Estimation

  -----------------------------------------

  Access Path: TableScan

    Cost:  23.42  Resp: 23.42  Degree: 0

      Cost_io: 20.00  Cost_cpu: 9538541

      Resp_io: 20.00  Resp_cpu: 9538541

  Access Path: index (AllEqRange)

    Index: TMP_INDEX

    resc_io: 134.00  resc_cpu: 7239716

    ix_sel: 0.38935  ix_sel_with_filters: 0.38935

    Cost: 136.60  Resp: 136.60  Degree: 1

  Best:: AccessPath: TableScan

         Cost: 23.42  Degree: 1  Resp: 23.42  Card: 16036.00  Bytes: 0

當兩個引數設為預設值時,sql選擇了意料之中的全表掃描,依據上文提到的公式計算一下

io_cost = (blevel + (leaf_blocks + clustering_factor) * selectivity) * optimizer_index_cost_adj/100 = (1 + (52  + 290) * 0.38935 ) * 1= 134.1

io_cost = {(blevel + leaf_blocks*selectivity) * (1 – optimizer_index_caching/100) + clustering_factor * selectivity} * (optimizer_index_cost_adj/100)

              =(( 1 + 52 * 0.38935 ) * 1 + 290 * 0.38935 ) * 1 = 134.1

CBO計算結果大致一樣

 

2

optimizer_index_cost_adj            = 10

optimizer_index_caching             = 0

optimizer_index_cost_adj100改為10,依據上述公式,indexScanio cost應該為案例1中的10%

SQL> set autotrace traceonly

SQL> alter session set events '10053 trace name context forever, level 12';

 

Session altered.

SQL> select * from tmp_t where wner='PUBLIC';

 

16036 rows selected.

 

 

Execution Plan

----------------------------------------------------------

Plan hash value: 1018746618

 

-----------------------------------------------------------------------------------------

| Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| Time     |

-----------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT            |           | 16036 |   187K|    14   (8)| 00:00:01 |

|   1 |  TABLE ACCESS BY INDEX ROWID| TMP_T     | 16036 |   187K|    14   (8)| 00:00:01 |

|*  2 |   INDEX RANGE SCAN          | TMP_INDEX | 16036 |       |     2   (0)| 00:00:01 |

-----------------------------------------------------------------------------------------

 

Predicate Information (identified by operation id):

---------------------------------------------------

 

   2 - access("OWNER"='PUBLIC')

 

 

Statistics

----------------------------------------------------------

          0  recursive calls

          0  db block gets

       2192  consistent gets

          0  physical reads

          0  redo size

     354186  bytes sent via SQL*Net to client

      12251  bytes received via SQL*Net from client

       1071  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

      16036  rows processed

SQL> alter session set events '10053 trace name context off';

 

Session altered.

跟蹤檔案

 

  Access Path: TableScan

    Cost:  23.42  Resp: 23.42  Degree: 0

      Cost_io: 20.00  Cost_cpu: 9538541

      Resp_io: 20.00  Resp_cpu: 9538541

  Access Path: index (AllEqRange)

    Index: TMP_INDEX

    resc_io: 134.00  resc_cpu: 7239716

    ix_sel: 0.38935  ix_sel_with_filters: 0.38935

    Cost: 13.66  Resp: 13.66  Degree: 1

  Best:: AccessPath: IndexRange  Index: TMP_INDEX

         Cost: 13.66  Degree: 1  Resp: 13.66  Card: 16036.00  Bytes: 0

將引數代入公式

io_cost = (blevel + (leaf_blocks + clustering_factor) * selectivity) * optimizer_index_cost_adj/100 = (1 + (52  + 290) * 0.38935 ) * 1/10= 13.4

io_cost = {(blevel + leaf_blocks*selectivity) * (1 – optimizer_index_caching/100) + clustering_factor * selectivity} * (optimizer_index_cost_adj/100)

              =(( 1 + 52 * 0.38935 ) * 1 + 290 * 0.38935 ) * 1/10 = 13.4

實際結果和預料的一樣,indexScancost下降為原來的十分之一,此時低於tableScan,故CBO選擇了索引掃描

 

3

optimizer_index_cost_adj            = 10

optimizer_index_caching             = 100

Table Stats::

  Table: TMP_T  Alias: TMP_T

    #Rows: 41187  #Blks:  49  AvgRowLen:  12.00

Index Stats::

  Index: TMP_INDEX  Col#: 2

LVLS: 1  #LB: 52  #DK: 57  LB/K: 1.00  DB/K: 5.00  CLUF: 290.00

…….

  Access Path: TableScan

    Cost:  23.42  Resp: 23.42  Degree: 0

      Cost_io: 20.00  Cost_cpu: 9538541

      Resp_io: 20.00  Resp_cpu: 9538541

  Access Path: index (AllEqRange)

    Index: TMP_INDEX

    resc_io: 134.00  resc_cpu: 7239716

    ix_sel: 0.38935  ix_sel_with_filters: 0.38935

    Cost: 13.66  Resp: 13.66  Degree: 1

  Best:: AccessPath: IndexRange  Index: TMP_INDEX

         Cost: 13.66  Degree: 1  Resp: 13.66  Card: 16036.00  Bytes: 0

選擇索引所用的cost根案例2的一樣,沒有發生變化

計算cost

io_cost = (blevel + (leaf_blocks + clustering_factor) * selectivity) * optimizer_index_cost_adj/100 = (1 + (52  + 290) * 0.38935 ) * 1/10= 13.4

io_cost = {(blevel + leaf_blocks*selectivity) * (1 – optimizer_index_caching/100) + clustering_factor * selectivity} * (optimizer_index_cost_adj/100)

              =(( 1 + 52 * 0.38935 ) * 0 + 290 * 0.38935 ) * 1/10 = 11.2

CBO在計算索引的io時,似乎更傾向於公式1,更改optimizer_index_caching對其影響微乎其微

 

 

其實更改這兩個引數唯一可能影響的是CBO生成執行計劃時到底選擇全表掃描還是索引掃描,並不能更改兩種訪問路徑的實際邏輯讀,因此使用時應該倍加小心才對,至少目前我還沒見過生產庫上的應用案例。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15480802/viewspace-736602/,如需轉載,請註明出處,否則將追究法律責任。

相關文章