首页 > 代码库 > optimizer_index_cost_adj

optimizer_index_cost_adj

Oracle在选择不同的访问路径时,会对全表扫描和索引扫描进行比较评估. 在比较的时候,Oracle会把索引扫描的成本转换为全表扫描的成本,和全表扫描的COST进行比较.这个转换需要一个转换因子. 就是optimizer_index_cost_adj:  optimizer_index_cost_adj * (Index Scan Cost) = 等价的 Full Scan Cost。

所以 optimizer_index_cost_adj = 等价的 Full Scan Cost  /  Index Scan Cost。

 

我们来做个试验,看是不是这样的。我们先创建一个表,建立索引然后收集统计信息。然后看一下默认的optimizer_index_cost_adj=100. 但这里存的其实是百分数,所以真正的optmizer_index_cost_adg=1.

SQL> create table t as select * from dba_users;Table created.SQL> create index t_username on t(username);Index created.SQL>  exec dbms_stats.gather_table_stats(SYS,T,cascade=>true);PL/SQL procedure successfully completed.SQL>SQL> show parameter optimizer_index_cost_adjNAME                                 TYPE                              VALUE------------------------------------ --------------------------------- ------------------------------optimizer_index_cost_adj             integer                           100SQL>
View Code

 

现在的index cost=2.

SQL> set linesize 180SQL> set autotrace traceonlySQL> select DEFAULT_TABLESPACE from t where username=CITOSADMIN;------------------------------------------------------------------------------------------| Id  | Operation                   | Name       | Rows  | Bytes | Cost (%CPU)| Time     |------------------------------------------------------------------------------------------|   0 | SELECT STATEMENT            |            |     1 |    17 |     2   (0)| 00:00:01 ||   1 |  TABLE ACCESS BY INDEX ROWID| T          |     1 |    17 |     2   (0)| 00:00:01 ||*  2 |   INDEX RANGE SCAN          | T_USERNAME |     1 |       |     1   (0)| 00:00:01 |------------------------------------------------------------------------------------------

现在的full table scan cost 也是等于2

SQL> select /*+ full(t) */ DEFAULT_TABLESPACE from t where username=CITOSADMIN;--------------------------------------------------------------------------| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |--------------------------------------------------------------------------|   0 | SELECT STATEMENT  |      |     1 |    17 |     2   (0)| 00:00:01 ||*  1 |  TABLE ACCESS FULL| T    |     1 |    17 |     2   (0)| 00:00:01 |--------------------------------------------------------------------------

 

我们设置该参数为1000,因为存储的是百分数,所以现在真正的optimizer_index_cost_adg=10;

alter session set optimizer_index_cost_adj = 1000;

现在index 的cost变成了:20=2*10

SQL> select /*+ index(t t_username) */ DEFAULT_TABLESPACE from t where username=CITOSADMIN;------------------------------------------------------------------------------------------| Id  | Operation                   | Name       | Rows  | Bytes | Cost (%CPU)| Time     |------------------------------------------------------------------------------------------|   0 | SELECT STATEMENT            |            |     1 |    17 |    20   (0)| 00:00:01 ||   1 |  TABLE ACCESS BY INDEX ROWID| T          |     1 |    17 |    20   (0)| 00:00:01 ||*  2 |   INDEX RANGE SCAN          | T_USERNAME |     1 |       |    10   (0)| 00:00:01 |------------------------------------------------------------------------------------------

 

所以这个参数就是这样影响CBO的执行计划的。