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_adj NAME TYPE VALUE ------------------------------------ --------------------------------- ------------------------------ optimizer_index_cost_adj integer 100 SQL>
现在的index cost=2.
SQL> set linesize 180 SQL> set autotrace traceonly SQL> 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的执行计划的。
optimizer_index_cost_adj,布布扣,bubuko.com
时间: 2024-10-11 03:56:23