oracle有两种优化器:基于规则的优化器(rbo,rule based optimizer),和基于成本/代价的优化器(cbo,cost based optimizer)。
我们要确定数据库运行在何种优化模式下,相应的参数是:optimizer_mode。可在sql命令中中运行show parameter optimizer_mode
来查看。
optimizer_mode 中常有五个参数值:CHOOSE、ALL_ROWS、FIRST_ROWS_N、FIRST_ROWS、RULE,例如:oracle 9i,而也有例外,比如oracle 10g少了RULE和CHOOSE
一、CHOOSE
这个是Oracle的默认值。采用这个值时,Oracle即可以采用基于规则RBO,也可以采用基于代价CBO,到底使用那个值,取决于当前SQL的被访问的表中是不是有可以使用的统计信息。
如果有多个被访问的表,其中有一个或多个有统计信息,那么Oralce会对没有统计信息的表进行采样统计(即不全部采样),统计完成后,使用基于代价的优化方法CBO。
如果所有被访问的表都没有统计信息,Oracle就会采用基于规则的优化方法RBO。
二、ALL_ROWS
优化器将寻找能够在最短的时间内完成语句的执行计划。
不管是不是有统计信息,全部采用基于成本的优化方法CBO。
设置为这种CBO模式以后,将保证消耗的所有计算资源最小,尽管有时查询结束以后没有结果返回。all_rows的优化模式更倾向于全表扫描,而不是全索引扫描和利用索引排序,因此这种优化模式适合于数据查看实时性不是那么强的数据仓库、决策支持系统和面向批处理的数据库(batch-oriented databases)等。
三、FIRST_ROWS
CBO模式,使用成本和试探法相结合的方法,查找一种可以最快返回前面少数行的方法;这个参数主要用于向后兼容。
在oracle 9i之后这一选项已经过时,出于向后兼容的目的保留了这一选项,**该选项的作用在于寻找能够在最短的时间内返回结果集的第一行的执行计划。这一规则倾向于促使优化器使用索引访问路径,偶尔会出现非常不恰当的访问路径。
设置为这种CBO模式以后,SQL语句返回结果的速度会尽可能的快,而不管系统全部的查询是否会耗时较长或者耗系统资源过多。由于利用索引会使查询速度加快,所以first_rows 优化模式会在全表扫描上进行索引扫描。这种优化模式一般适合于一些OLTP系统,满足用户能够在较短时间内看到较小查询结果集的要求。
四、FIRST_ROWS_N
不管是不是有统计信息,全部采用基于成本的优化方法CBO,并以最快的速度,返回前N行记录。
N的值可以为1,10,100,1000,优化器首先通过彻底分析第一个连接顺序来估计返回行的总数目。这样就可以知道查询可能获得的整个数据集的片段,并重新启动整个优化过程,其目标在于找到能够以最小的资源消耗返回整个数据片段的执行计划。
Oracle 9i 对一些预期返回结果集的数据量小的SQL语句优化模式进行了加强,增加了四个参数值:first_rows_1、first_rows_10、first_rows_100、first_rows_1000。CBO通过first_rows_n中的 n 值,决定了返回结果集数量的基数,我们可能仅仅需要查询结果集中的一部分,CBO就根据这样的n 值来决定是否使用索引扫描。
五、RULE
这个参数正好和ALL_ROWS相反,不管是不是统计信息,全部采用基于规则rbo的优化方法。
基于规则的优化器模式,RBO,是早期Oracle版本使用过的一种优化模式。由于RBO不支持自1994年Oracle版本的新特性,如bitmap indexes,table partitions,function-based indexes等,所以在以后Oracle版本中已经不再更新RBO,并且也不推荐用户使用RBO这种优化模式了。
更改 optimizer_mode 的参数:
alter session set optimizer_mode='optimizer_mode的参数';