A-A+
有关索引-参数optimizer_index_cost_adj的设置
关于参数optimizer_index_cost_adj的设置
概述:
参数optimizer_index_cost_adj的默认值是100,值域是0-10000的任意值。参数数值越低,越可能让优化器使用索引。
注意:
1)一般建议在会话级别设置该参数
2)在oltp系统建议使用很低的参数值,如5或者10,以强制优化器使用索引
数据库版本信息
SQL> select * from gv$version;
INST_ID BANNER
---------- --------------------------------------------------------------------------------
1 Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
1 PL/SQL Release 11.2.0.3.0 - Production
1 CORE 11.2.0.3.0 Production
1 TNS for Linux: Version 11.2.0.3.0 - Production
1 NLSRTL Version 11.2.0.3.0 - Production
参数默认值
SQL> show parameter optimizer_index_cost_adj NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ optimizer_index_cost_adj integer 100
关于该参数值的计算
SQL> select event,average_wait from v$system_event where event like 'db file s%read';
EVENT AVERAGE_WAIT
---------------------------------------------------------------- ------------
db file sequential read 1.28
db file scattered read 2.2
SQL> select (1.28/2.2)*100 pct from dual;
PCT
----------
58.1818182
故参数值应该设置为58左右
下边测试一下该参数的用途
SQL> create table yallonking as select rownum id,'yallonking' name from dual connect by rownum<101;
Table created.
SQL> create index idx_yallonking_id on yallonking(id);
Index created.
SQL> set autot traceonly
SQL> select * from yallonking where id<50;
49 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 2582482548
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 49 | 1225 | 2 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| YALLONKING | 49 | 1225 | 2 (0)| 00:00:01 |
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("ID"<50)
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
10 recursive calls
0 db block gets
15 consistent gets
0 physical reads
0 redo size
1587 bytes sent via SQL*Net to client
556 bytes received via SQL*Net from client
5 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
49 rows processed
下边修改该参数
SQL> alter session set optimizer_index_cost_adj=58; Session altered.
继续执行上边的sql,会发现此时该sql开始走索引,故该参数在这时起了作用。
SQL> select * from yallonking where id<50;
49 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 2645553055
-------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 49 | 1225 | 1 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| YALLONKING | 49 | 1225 | 1 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IDX_YALLONKING_ID | 49 | | 1 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID"<50)
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
9 recursive calls
0 db block gets
16 consistent gets
0 physical reads
0 redo size
2121 bytes sent via SQL*Net to client
556 bytes received via SQL*Net from client
5 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
49 rows processed
以下是在内存中缓存数据后的一个对比的例子
SQL> alter session set optimizer_index_cost_adj=90;
Session altered.
SQL> select * from yallonking where id<50;
49 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 2645553055
-------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 49 | 1225 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| YALLONKING | 49 | 1225 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IDX_YALLONKING_ID | 49 | | 1 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID"<50)
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
9 recursive calls
0 db block gets
16 consistent gets
0 physical reads
0 redo size
2121 bytes sent via SQL*Net to client
556 bytes received via SQL*Net from client
5 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
49 rows processed
SQL> alter session set optimizer_index_cost_adj=100;
Session altered.
SQL> select * from yallonking where id<50;
49 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 2582482548
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 49 | 1225 | 2 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| YALLONKING | 49 | 1225 | 2 (0)| 00:00:01 |
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("ID"<50)
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
7 consistent gets
0 physical reads
0 redo size
1587 bytes sent via SQL*Net to client
556 bytes received via SQL*Net from client
5 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
49 rows processed
该例子说明,在全表扫描的时候才需要7次一致性读,但是走索引确有16次一致性读以及9次递归调用。因为测试查询的内容不完全在索引中,所以在使用索引的时候,oracle不但要读取数据块,而且还得读取索引块,继而增加了块的读的次数。
小结:参数optimizer_index_cost_adj会影响数据库对索引的使用的选择性。但是,该参数的调整需要十分谨慎,因为在oracle更高的版本中基于cost的优化器的选择往往比人为做出的决定更加准确。