optimizer_index_caching和optimizer_index_cost_adj兩個引數說明

lhrbest發表於2017-12-01

optimizer_index_caching和optimizer_index_cost_adj兩個引數說明





OPTIMIZER_INDEX_COST_ADJ

Property Description
Parameter type Integer
Default value 100
Modifiable ALTER SESSION, ALTER SYSTEM
Range of values 1 to 10000

OPTIMIZER_INDEX_COST_ADJ lets you tune optimizer behavior for access path selection to be more or less index friendly—that is, to make the optimizer more or less prone to selecting an index access path over a full table scan.

The default for this parameter is 100 percent, at which the optimizer evaluates index access paths at the regular cost. Any other value makes the optimizer evaluate the access path at that percentage of the regular cost. For example, a setting of 50 makes the index access path look half as expensive as normal.

Note:

The adjustment does not apply to user-defined cost functions for domain indexes.

See Also:

for more information on setting this parameter, and on its relationship to



OPTIMIZER_INDEX_CACHING

Property Description
Parameter type Integer
Default value 0
Modifiable ALTER SESSION, ALTER SYSTEM
Range of values 0 to 100

OPTIMIZER_INDEX_CACHING lets you adjust the behavior of cost-based optimization to favor nested loops joins and IN-list iterators.

The cost of executing an index using an IN-list iterator or of executing a nested loops join when an index is used to access the inner table depends on the caching of that index in the buffer cache. The amount of caching depends on factors that the optimizer cannot predict, such as the load on the system and the block access patterns of different users.

You can modify the optimizer's assumptions about index caching for nested loops joins and IN-list iterators by setting this parameter to a value between 0 and 100 to indicate the percentage of the index blocks the optimizer should assume are in the cache. Setting this parameter to a higher value makes nested loops joins and IN-list iterators look less expensive to the optimizer. As a result, it will be more likely to pick nested loops joins over hash or sort-merge joins and to pick indexes using IN-list iterators over other indexes or full table scans. The default for this parameter is 0, which results in default optimizer behavior.

See Also:

for more information on setting this parameter






一、optimizer_index_cost_adj引數
最佳化器計算透過索引掃描訪問表資料的cost開銷,可以透過這個引數進行調整。引數可用值的範圍為1到10000。預設值為100,超過100後越大則越會使索引掃描的COST開銷越高(計算的),從而導致查詢最佳化器更加傾向於使用全表掃描。相反,值越小於100,計算出來的索引掃描的開銷就越低。
注意:
1、這裡描述的開銷,僅僅為最佳化器評估出來的而已,而非實際執行的開銷;例如同樣的SQL語句,同樣的執行路徑,修改這個引數以後,計算出來的cost不同,但是,SQL語句執行的實際物理路徑、時間、邏輯讀都是一樣的。
2、這個引數影響最佳化器評估索引訪問的IO開銷
3、可以參見後面的示例進一步理解這個引數

二、optimizer_index_caching引數
用於在執行in-list遍歷和巢狀迴圈連線時,最佳化器評估已經存在於buffer cache中的索引塊的數量(以百分比的方式)。引數的取值範圍是0到100,預設值為0,取值越大就越減少最佳化器在評估In-list和巢狀迴圈連線的索引掃描的開銷COST。
1、這裡的描述僅僅為最佳化器的評估結果。換句話說,它不是用來指定資料庫實際快取的每個索引塊的數量
2、可以參見後面的示例進一步理解這個引數

三、索引範圍掃描的成本計算公式(與兩個引數相結合)
cost = { (blevel+leaf_blocks * effective index selectivity)*(1-optimizer_index_caching/100)+
          cluster_factor * effective table selectivity)*(optimizer_index_cost_adj/100) }
說明
1、blevel=索引的層數,即dba_indexes檢視中的blevel列值
2、leaf_blocks為索引的葉子塊數量,即dba_indexes檢視中的leaf_blocks列值
3、effective index selectivity指的是SQL語句中用於索引掃描的謂詞驅動條件的列欄位的選擇率(where條件中)
4、cluster_factor為索引的聚簇因子(表示索引資料與表資料排序後的相近程度)
5、effective table selectivity指的是SQL where條件中能夠在索引上進行過濾的所有謂詞列欄位的選擇率(可以理解為透過索引掃描後(包含驅動和過濾),最後透過rowid定位表的數量)
6、一般是4、5兩個部分往往是整個計算公式中權重最大的因素。

注意
1、從上面的成本計算公式和說明,我們知道,optimizer_index_cost_adj引數對最佳化器的影響要遠遠大於optimizer_index_caching引數
2、隨著最佳化器越來越智慧這兩個引數的作用已經慢慢被 系統統計資訊 給替換了。
3、10gR2開始,這兩個引數的值儘量保持為預設值。如果實在需要調整,請嚴格測試!


四、optimizer_index_cost_adj引數示例
SQL> create table t as select rownum rn ,object_name name from dba_objects a where rownum<5000;
Table created.
SQL> create index t_idx on t(rn);
Index created.
SQL> BEGIN
  2  
  3    DBMS_STATS.GATHER_TABLE_STATS(OWNNAME=>'SYS',
  4                                  TABNAME=>'T',
  5                                  ESTIMATE_PERCENT=>30,
  6                                  METHOD_OPT=>'FOR ALL COLUMNS SIZE 1',
  7                                  NO_INVALIDATE=>FALSE,
  8                                  CASCADE=>TRUE,
  9                                  DEGREE => 4); 
 10  END
 11  /
PL/SQL procedure successfully completed.
SQL>  explain plan for select * from t where rn<200;
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value470836197

-------------------------------------------------------------------------------------
| Id  | Operation                   | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |       |   199 |  4179 |     3   (0)| 00:00:35 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T     |   199 |  4179 |     3   (0)| 00:00:35 |
|*  2 |   INDEX RANGE SCAN          | T_IDX |   199 |       |     2   (0)| 00:00:24 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("RN"<200)

14 rows selected.

SQL> alter session set optimizer_index_cost_adj=50;
Session altered.
SQL> explain plan for select * from t where rn<200;
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value470836197
-------------------------------------------------------------------------------------
| Id  | Operation                   | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |       |   199 |  4179 |     2   (0)| 00:00:18 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T     |   199 |  4179 |     2   (0)| 00:00:18 |
|*  2 |   INDEX RANGE SCAN          | T_IDX |   199 |       |     1   (0)| 00:00:12 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("RN"<200)
14 rows selected.

SQL> alter session set optimizer_index_cost_adj=500;
Session altered.
SQL>  explain plan for select * from t where rn<200;
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value1601196873
-------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |   199 |  4179 |     6   (0)| 00:01:10 |
|*  1 |  TABLE ACCESS FULL| T    |   199 |  4179 |     6   (0)| 00:01:10 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("RN"<200)
13 rows selected.


五、optimizer_index_caching引數示例
IN-LIST示例
SQL> set linesize 200 pagesize 9999
SQL> explain plan for select * from t where rn in (1,2,3,4,5,6,7,100,130,200,240,2000);
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value3506647781
--------------------------------------------------------------------------------------
| Id  | Operation                    | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |       |    12 |   252 |     4   (0)| 00:00:43 |
|   1 |  INLIST ITERATOR             |       |       |       |            |          |
|   2 |   TABLE ACCESS BY INDEX ROWID| T     |    12 |   252 |     4   (0)| 00:00:43 |
|*  3 |    INDEX RANGE SCAN          | T_IDX |    12 |       |     3   (0)| 00:00:31 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   3 - access("RN"=1 OR "RN"=2 OR "RN"=3 OR "RN"=4 OR "RN"=5 OR "RN"=6 OR
              "RN"=7 OR "RN"=100 OR "RN"=130 OR "RN"=200 OR "RN"=240 OR "RN"=2000)
16 rows selected.
SQL> alter session set optimizer_index_caching=10;
Session altered.
SQL>  explain plan for select * from t where rn in (1,2,3,4,5,6,7,100,130,200,240,2000);

Explained.

SQL>  select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value3506647781

--------------------------------------------------------------------------------------
| Id  | Operation                    | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |       |    12 |   252 |     3   (0)| 00:00:31 |
|   1 |  INLIST ITERATOR             |       |       |       |            |          |
|   2 |   TABLE ACCESS BY INDEX ROWID| T     |    12 |   252 |     3   (0)| 00:00:31 |
|*  3 |    INDEX RANGE SCAN          | T_IDX |    12 |       |     2   (0)| 00:00:19 |   --可以看到cost確實降低了
--------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - access("RN"=1 OR "RN"=2 OR "RN"=3 OR "RN"=4 OR "RN"=5 OR "RN"=6 OR
              "RN"=7 OR "RN"=100 OR "RN"=130 OR "RN"=200 OR "RN"=240 OR "RN"=2000)

16 rows selected
巢狀迴圈連線示例:
SQL> explain plan for select /*+ use_nl(a b) */ * from t a,t b where a.rn=b.rn and b.name='sss';
Explained.
SQL>  select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value752965310
--------------------------------------------------------------------------------------
| Id  | Operation                    | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |       |     1 |    42 |     8   (0)| 00:01:34 |
|   1 |  NESTED LOOPS                |       |       |       |            |          |
|   2 |   NESTED LOOPS               |       |     1 |    42 |     8   (0)| 00:01:34 |
|*  3 |    TABLE ACCESS FULL         | T     |     1 |    21 |     6   (0)| 00:01:10 |
|*  4 |    INDEX RANGE SCAN          | T_IDX |     1 |       |     1   (0)| 00:00:12 |
|   5 |   TABLE ACCESS BY INDEX ROWID| T     |     1 |    21 |     2   (0)| 00:00:24 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   3 - filter("B"."NAME"='sss')
   4 - access("A"."RN"="B"."RN")
18 rows selected.
SQL> alter session set optimizer_index_caching=10;
Session altered.
SQL> explain plan for select /*+ use_nl(a b) */ * from t a,t b where a.rn=b.rn and b.name='sss';
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value752965310
--------------------------------------------------------------------------------------
| Id  | Operation                    | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |       |     1 |    42 |     7   (0)| 00:01:22 |
|   1 |  NESTED LOOPS                |       |       |       |            |          |
|   2 |   NESTED LOOPS               |       |     1 |    42 |     7   (0)| 00:01:22 |  --可以看到cost確實降低了
|*  3 |    TABLE ACCESS FULL         | T     |     1 |    21 |     6   (0)| 00:01:10 |
|*  4 |    INDEX RANGE SCAN          | T_IDX |     1 |       |     0   (0)| 00:00:01 |
|   5 |   TABLE ACCESS BY INDEX ROWID| T     |     1 |    21 |     1   (0)| 00:00:12 |
--------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - filter("B"."NAME"='sss')
   4 - access("A"."RN"="B"."RN")

18 rows selected.



非in-list和巢狀迴圈操作,調整這個引數時,不會影響oracle最佳化器成本的運算,如下
SQL> set linesize 200 pagesize 999
SQL> explain plan for select * from t where rn<200;
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value470836197
-------------------------------------------------------------------------------------
| Id  | Operation                   | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |       |   199 |  4179 |     3   (0)| 00:00:35 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T     |   199 |  4179 |     3   (0)| 00:00:35 |
|*  2 |   INDEX RANGE SCAN          | T_IDX |   199 |       |     2   (0)| 00:00:24 |
-------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("RN"<200)
14 rows selected.
SQL> alter session set optimizer_index_caching=1;
Session altered.
SQL> explain plan for select * from t where rn<200;
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value470836197
-------------------------------------------------------------------------------------
| Id  | Operation                   | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |       |   199 |  4179 |     3   (0)| 00:00:35 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T     |   199 |  4179 |     3   (0)| 00:00:35 |
|*  2 |   INDEX RANGE SCAN          | T_IDX |   199 |       |     2   (0)| 00:00:24 |  --可以看到cost確實沒有改變
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("RN"<200)
14 rows selected.






OPTIMIZER_INDEX_COST_ADJ
這個初始化引數代表一個百分比,取值範圍在1到10000之間.
該參數列示索引掃描全表掃描成本的比較。預設值100表示索引掃描成本等價轉換與全表掃描成本。

這些引數對於CBO的執行具有重大影響,其預設值對於資料庫來說通常需要調整。
一般來說對於OPTIMIZER_INDEX_CACHING可以設定為90左右
對於大多數OLTP系統,OPTIMIZER_INDEX_COST_ADJ可以設定在10到50之間。對於資料倉儲和DSS系統,
可能不能簡單的把OPTIMIZER_INDEX_COST_ADJ設定為50,通常我們需要反覆調整取得一個合理值.

更為具體的可以根據統計資訊,db file scattered reads/db file sequential reads來計算.

本文透過實驗對該引數的使用作出探討和說明.

我們看到optimizer_index_cost_adj的預設值為100.

 

[oracle@jumper udump]$ sqlplus eygle/eygle

SQL*Plus: Release 9.2.0.3.0 - Production on Mon Jun 28 17:11:15 2004

Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.

Connected to:
Oracle9i Enterprise Edition Release 9.2.0.3.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.3.0 - Production

SQL> show parameter optimizer_index_cost_adj

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
optimizer_index_cost_adj integer 100
SQL>

建立測試表:

 

SQL> create table t as select * from dba_objects;

Table created.

SQL> create index ind_owner on t(owner);

Index created.

SQL> analyze table t compute statistics;

Table analyzed.

 

我們分別觀察一下全表掃描和索引訪問的成本:

 

SQL> set autotrace traceonly


SQL> select * from t where owner='EYGLE';

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=14 Card=476 Bytes=36652)
1 0 TABLE ACCESS (FULL) OF 'T' (Cost=14 Card=476 Bytes=36652)



SQL> select /*+ index(t ind_owner) */ * from t where owner='EYGLE';

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=16 Card=476 Bytes=36652)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'T' (Cost=16 Card=476 Bytes=36652)
2 1 INDEX (RANGE SCAN) OF 'IND_OWNER' (NON-UNIQUE) (Cost=2 Card=476)

 

Oracle在選擇不同的訪問路徑時,會對全表掃描和索引掃描進行比較評估.

在比較的時候,Oracle會把索引掃描的成本轉換為全表掃描的成本,和全表掃描的COST進行比較.這個轉換需要一個轉換因子.
就是optimizer_index_cost_adj:

optimizer_index_cost_adj * (Index Scan Cost) = 等價的 Full Scan Cost

這個 等價的 Full Scan Cost 就是來和全表掃描成本進行比較的.

而這個轉換因子的臨界值實際上就是Full Scan Cost 和 Index Scan Cost的比值.

即:


optimizer_index_cost_adj
 = Full Scan Cost / Index Scan Cost

 

SQL> set autotrace off
SQL> select (14/16)*100 from dual;

(14/16)*100
-----------
87.5

1 row selected.

 

我們透過調整optimizer_index_cost_adj來看一下執行計劃的變化:

 

SQL> set autotrace traceonly

SQL> alter session set optimizer_index_cost_adj = 87;

Session altered.

SQL> select * from t where owner='EYGLE';

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=14 Card=476 Bytes=36652)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'T' (Cost=14 Card=476 Bytes=36652)
2 1 INDEX (RANGE SCAN) OF 'IND_OWNER' (NON-UNIQUE) (Cost=2 Card=476)

此時使用索引成本較低.等價全表掃描成本為:

87% * (Index Scan Cost) < Full Scan Cost

此時Oracle選擇了索引.

SQL> alter session set optimizer_index_cost_adj = 88;

Session altered.

SQL> select * from t where owner='EYGLE';

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=14 Card=476 Bytes=36652)
1 0 TABLE ACCESS (FULL) OF 'T' (Cost=14 Card=476 Bytes=36652)

此時使用索引成本較高.等價全表掃描成本為:

88% * (Index Scan Cost) > Full Scan Cost

所以Oracle選擇了全表掃描.



 


參考文件:

 














About Me

.............................................................................................................................................

● 本文作者:小麥苗,部分內容整理自網路,若有侵權請聯絡小麥苗刪除

● 本文在itpub(http://blog.itpub.net/26736162/abstract/1/)、部落格園(http://www.cnblogs.com/lhrbest)和個人微信公眾號(xiaomaimiaolhr)上有同步更新

● 本文itpub地址:http://blog.itpub.net/26736162/abstract/1/

● 本文部落格園地址:http://www.cnblogs.com/lhrbest

● 本文pdf版、個人簡介及小麥苗雲盤地址:http://blog.itpub.net/26736162/viewspace-1624453/

● 資料庫筆試面試題庫及解答:http://blog.itpub.net/26736162/viewspace-2134706/

● DBA寶典今日頭條號地址:

.............................................................................................................................................

● QQ群號:230161599(滿)、618766405

● 微信群:可加我微信,我拉大家進群,非誠勿擾

● 聯絡我請加QQ好友646634621,註明新增緣由

● 於 2017-11-01 09:00 ~ 2017-11-30 22:00 在魔都完成

● 文章內容來源於小麥苗的學習筆記,部分整理自網路,若有侵權或不當之處還請諒解

● 版權所有,歡迎分享本文,轉載請保留出處

.............................................................................................................................................

小麥苗的微店

小麥苗出版的資料庫類叢書http://blog.itpub.net/26736162/viewspace-2142121/

.............................................................................................................................................

使用微信客戶端掃描下面的二維碼來關注小麥苗的微信公眾號(xiaomaimiaolhr)及QQ群(DBA寶典),學習最實用的資料庫技術。

   小麥苗的微信公眾號      小麥苗的DBA寶典QQ群2     《DBA筆試面寶典》讀者群       小麥苗的微店

.............................................................................................................................................

optimizer_index_caching和optimizer_index_cost_adj兩個引數說明
DBA筆試面試講解群
《DBA寶典》讀者群 歡迎與我聯絡



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

相關文章