Oracle 10g 对这个参数进行了修改。只有3个值,分别是first_rows_n ; first_rows ;all_rows(默认值)
先从9i讲起吧。有5个值:choose (默认值); rules ; first_rows ;first_rows_N ;all_rows
默认值为choose.采用这个值的时候,基于规则RBO,也可以采用给予代价的CBO。到底采用哪个,取决于当前的sql的被访问的表中是不是有可以使用的统计信息。如果有多个被访问的表,其中有一个或者多个有统计信息,那么oracle会对没有统计信息的表进行采用统计(不全部采样),统计后,使用CBO。如果所有的表都没有统计信息,那么采用RBO
first_rows
在oracle9i之后这个选项已经过时,处于向后兼容的目的保留的这一选项,该项的作用在于寻找能够在更短的时间内返回结果集的第一行的执行计划。这一规则倾向于使用优化器使用索引访问路径,偶尔也会出现不恰当的访问路径。该模式一半适合用于一些OLTP系统满足用户在短时间内查看较小的查询结果集要求。
all_rows优化器将寻找能够在最短的时间内完成语句的执行计划,保证消耗的所有计算资源最小。
first_rows_N 其中N的值可以使1,10,100,1000
优化器首先通过彻底分析第一个连接的顺序来估计返回行的总数目。这样可以知道查询可能获得的整个数据集的片段,并重新启动这个优化过程,其目标在于找到能够最小的资源小行返回整个数据片段的执行计划。
rule
基于规则的优化器模式。不支持bitmap indexes ,table paratitions,function_based indexes等。
--=================================================
另外特别要提到的是
当采用RBO,如果2个索引都能用,它会采有用后创建的索引。这是它最傻的地方。
表统计信息收集的方法有2种
Analyze table tablename compute statistics;
Dbms_stats包
例如dbms_stats.gather_table_stats(User,TableName,degree => 4,cascade => true);
这2个方法的优缺点介绍:
1、DBMS_STATS的优点 对于分区表,建议使用DBMS_STATS,而不是使用Analyze语句。
a) 可以并行进行,对多个用户,多个Table
b) 可以得到整个分区表的数据和单个分区的数据。
c) 可以在不同级别上Compute Statistics:单个分区,子分区,全表,所有分区
d) 可以倒出统计信息
e) 可以用户自动收集统计信息
2、DBMS_STATS的缺点
a) 不能Validate Structure
b) 不能收集CHAINED ROWS, 不能收集CLUSTER TABLE的信息,这两个仍旧需要使用Analyze语句。
c) DBMS_STATS 默认不对索引进行Analyze,因为默认Cascade是False,需要手工指定为True
删除表统计信息方法
analyze table table_name delete statistics;
dbms_stats.DELETE_TABLE_STATS
设定选用哪种优化模式: (选项值具体按ORACLE版本来)
A、Instance级别我们可以通过在initSID.ora文件中设定OPTIMIZER_MODE=RULE/CHOOSE/FIRST_ROWS/ALL_ROWS如果没设定OPTIMIZER_MODE参数则默认用的是Choose方式。
B、Sessions级别通过ALTER SESSION SET OPTIMIZER_MODE=RULE/CHOOSE/FIRST_ROWS/ALL_ROWS来设定。
C、语句级别用Hint(/*+ ... */)来设定
为什么表的某个字段明明有索引,但执行计划却不走索引?
1、优化模式是不是all_rows的方式
2、表作过analyze,有统计信息
3、表很小,Oracle的优化器认为不值得走索引。