Oracle 优化器(Optimizer)
2017-03-20 10:26
337 查看
优化器概念
优化器具有分析SQL执行计划和路径的作用;一条SQL可能有多种执行计划,但在某一时点一定只有一种执行计划是最优的,花费时间是最少的。优化器的优化方式
RBO方式
基于规则的优化方式(Rule-Based Optimization,简称为RBO)。优化器在分析SQL语句时,所遵循的是Oracle内部预定的一些规则。例如一个where子句中的一列有索引时走索引。CBO方式
基于代价的优化方式(Cost-Based Optimization,简称为CBO)。依词义可知,它是看语句的代价(Cost)了,这里的代价主要指Cpu和内存。优化器在判断是否用这种方式时,主要参照的是表及索引的统计信息。统计信息给出表的大小、有少行、每行的长度等信息。这些统计信息起初在库内是没有的,是你在做analyze后才出现的,很多的时侯过期统计信息会令优化器做出一个错误的执行计划,因些我们应及时更新这些信息。可以在运行期间,采用hint灵活地采用优化方式,人工干预执行路径和方式。在Oracle8及以后的版本,Oracle列推荐用CBO的方式。
注意:不一定走索引就是优的 ,比如一个表只有两行数据,一次IO就可以完成全表的检索,而此时走索引时则需要两次IO,这时对这个表做全表扫描(full table scan)是最好的。
CHOOSE方式
设置缺省的Oracle优化器,可以通过对init.ora文件中OPTIMIZER_MODE参数的各种声明,如RULE,COST,CHOOSE,ALL_ROWS,FIRST_ROWS . 你当然也在SQL句级或是会话(session)级对其进行覆盖。为了使用基于成本的优化器(CBO, Cost-Based Optimizer) ,你必须经常运行analyze 命令,以增加数据库中的对象统计信息(object statistics)的准确性。如果数据库的优化器模式设置为选择性(CHOOSE),那么实际的Oracle优化器模式将和是否运行过analyze命令有关。如果table已经被analyze过, 优化器模式将自动成为CBO , 反之,数据库将采用RULE形式的优化器。
在缺省情况下,Oracle采用CHOOSE优化器,为了避免那些不必要的全表扫描(full table scan) ,你必须尽量避免使用CHOOSE优化器,而直接采用基于规则或者基于成本的Oracle优化器。
优化器的优化模式
优化模式包括Rule,Choose,First rows,All rows四种。Rule:不用多说,即走基于规则的方式。 (RBO优化方式)
Choose:这是我们应观注的,默认的情况下Oracle用的便是这种方式。指的是当一个表或或索引有统计信息,则走CBO的方式,如果表或索引没统计信息,表又不是特别的小,而且相应的列有索引时,那么就走索
4000
引,走RBO的方式
First Rows:它与Choose方式是类似的,所不同的是当一个表有统计信息时,它将是以最快的方式返回查询的最先的几行,从总体上减少了响应时间。
All Rows:也就是我们所说的Cost的方式,当一个表有统计信息时,它将以最快的方式返回表的所有的行,从总体上提高查询的吞吐量。没有统计信息则走基于规则的方式。
注意:First Rows和All Rows是有冲突的.如果想最快第返回给用户,就不可能传递更多的结果,这就是First Rows返回最先检索到的行(或记录);而All Rows是为了尽量将所有的结果返回给用户,由于量大,用户就不会很快得到返回结果.就象空车能跑得很快,重装车只能慢慢地跑;
优化器的优化模式的设定
Instance级别
通过在init<实例名>.ora文件中设定OPTIMIZER_MODE=RULE、
OPTIMIZER_MODE=CHOOSE、
OPTIMIZER_MODE=FIRST_ROWS、
OPTIMIZER_MODE=ALL_ROWS
OPTIMIZER_MODE参数默认用的是Choose这种方式。
init.ora和init<实例名>.ora都在$ORACLE_HOME/dbs目录下,可以用
find $ORACLE_HOME -name init*.ora
init.ora是对全体实例有效的;
init<实例名>.ora只对指定的实例有效.
Sessions级别
通过SQL> ALTER SESSION SET OPTIMIZER_MODE=<Mode>;来设定,将覆盖init.ora,init<实例名>.ora设定的优化模式
语句级别
采用HintsQ&A
问题:为什么有时一个表的某个字段明明有索引,当观察一些语的执行计划确不走索引呢?如何解决呢?原因:
你在Instance级别所用的是all_rows的方式
你的表的统计信息(最可能的原因)
你的表很小,上文提到过的,Oracle的优化器认为不值得走索引。
解决方法:
可以修改init.ora中的OPTIMIZER_MODE这个参数,把它改为Rule或Choose后重启数据库
更新表的统计信息
SQL>analyze table table_name delete statistics;
表小不走索引是对的,不用调的。
相关文章推荐
- Oracle 11g通过提高IO吞吐量(修改_db_file_optimizer_read_count)来优化全表扫描
- 说一说Oracle的优化器(Optimizer)
- Oracle的优化器(Optimizer) (CBO优化)
- Oracle 11g通过提高IO吞吐量(修改_db_file_optimizer_read_count)来优化全表扫描
- oracle的优化(3)――自动收集统计信息Auto Maintenance Tasks和动态采样optimizer_dynamic_sampling
- Oracle的优化器(Optimizer)
- Oracle的优化器(Optimizer)
- Oracle的优化器(Optimizer)
- Oracle Optimizer:迁移到使用基于成本的优化器-----系
- 说一说Oracle的优化器(Optimizer)
- Oracle的优化器(Optimizer) (CBO优化) 分享
- 转载:Oracle的优化器(Optimizer)
- Oracle的优化器(Optimizer)
- Oracle的优化器(Optimizer)
- oracle database query Optimizer 查询优化
- Oracle的优化器(Optimizer) (CBO优化) 分享
- Oracle 优化参数 optimizer_mode 介绍
- Oracle下优化控制器optimizer_mode参数设置
- Oracle的优化器(Optimizer)
- Oracle的优化器(Optimizer)