http://www.toadworld.com/KNOWLEDGE/KnowledgeXpertforOracle/tabid/648/TopicID/CBOI/Default.aspx
优化器是负责确定最有效的方式执行和产生结果的一个程序。根据表的大小、行的数量、数据块的密度、索引列和其他一些因素,可能有很多不同方式来获得一个 SQL 语句所要求的数据。但只有几个较有效、及时的方式。优化器的工作就是找到那些有效而及时的路径。
如果 SQL 语句需要表连接,那么不同的执行计划可能差异很大。对于每个 SQL 语句,优化器执行以下操作:
- 评估表达式和条件
- 转换语句,如果需要的话
- 选择优化器方法(基于规则、基于代价,所有行,或是前几行)
- 选择每个表的访问路径
- 选择连接顺序,如果连接多个表的话
- 选择连接表的方法
利用优化器,我们对于整体功能有很多不同的选择。我们可以选择使用基于规则的优化器(Rule-based optimizer,RBO),或者使用基于代价的优化器(Cost-based optimizer,CBO)。如果使用 CBO,我们可以选择优化器尽可能快地返回所有的行,尽可能快地返回几行,或是返回前 n 行(其中n 为 1,10,100,或 1000)。通过设置 optimizer_mode 初始化参数,DBA 确定优化器对整个实例的行为如何。优化器可以为每个会话进行不同的设置。
注意:在 Oracle 10g 中,虽然基于规则的优化器(RBO)仍然可用。但它已经不支持了。
设置优化器模式
可以为整个实例、一个会话或一个单独的 SQL 语句设置优化器模式或方法。优先级顺序是:SQL 语句覆盖会话模式的设置,会话模式覆盖整个实例的模式设置。
实例级别
DBA 可以通过 OPTIMIZER_MODE 初始化参数为整个实例设置优化器模式。这个参数不能动态改变。该参数有如下几个值,它们具有不同的行为:
- RULE 对所有 SQL 语句使用基于规则的方法,即使统计信息是可用的。该值自 Oracle 10g 中不再使用。
- ALL_ROWS 具有最好吞吐量(最小化响应时间)目标的优化,以返回所有满足查询的行。
- FIRST_ROWS_n 具有最好响应时间目标的优化,以返回 n 行数据,n 为 1,10,100,或 1000。
- FIRST_ROWS 优化器使用代价和启发式算法来查找返回前几行的最优执行计划。
- CHOOSE 如果一个 SQL 语句中至少有一个表的统计信息可用,或对于所有表的并行程序大于 1,那么就使用基于代价的方法,并采用具有最好吞吐量的优化。该值自 Oracle 10g 就不再使用。
- 如果所有表的统计信息都不可用,那么执行计划可能不是最优的
- 如果所有表根本没有统计信息,那么将使用基于规则的方法
查询 V$SYSTEM_PARAMETER 视图确定当前优化器的设置:
SQL> select name,value,isdefault,ismodified,description
2 from v$system_parameter
3 where name like '%optimizer_mode%';
NAME VALUE ISDEFAULT ISMODIFIED DESCRIPTION
--------------- ---------- ---------- ---------- --------------------
optimizer_mode ALL_ROWS TRUE FALSE optimizer mode
SQL>
另外,你也可以使用 V$SYSTEM_PARAMETER2 视图。
会话级别
对于一个单独的会话,设置优化器模式,会话模式会覆盖实例模式。可以利用命令改变会话的优化器模式。
可以查看 V$PARAMETER 视图确定当前会话的设置:
SQL> select name,value,isdefault,ismodified,description
2 from v$parameter
3 where name like '%optimizer_mode%';
NAME VALUE ISDEFAULT ISMODIFIED DESCRIPTION
--------------- ---------- ---------- ---------- --------------------
optimizer_mode ALL_ROWS TRUE FALSE optimizer mode
SQL> alter session set optimizer_mode=rule;
会话已更改。
SQL> select name,value,isdefault,ismodified,description
2 from v$parameter
3 where name like '%optimizer_mode%';
NAME VALUE ISDEFAULT ISMODIFIED DESCRIPTION
--------------- ---------- ---------- ---------- --------------------
optimizer_mode RULE TRUE MODIFIED optimizer mode
SQL>
语句级别
在 SQL 语句级别,应用程序开发者可以在 SQL 语句中“暗示”来影响优化器模式。SQL 语句将会覆盖会话和实例中的优化器设置。如下面语句:
SELECT /*+ ALLFIRST_ROWS */
EMPLOYEE_ID, LAST_NAME
FROM HR.EMPLOYEES E, HR.DEPT D
WHERE E.DEPARTMENT_ID = D.DEPARTMENT_ID
AND D.DEPARTMENT_ID=100;
其中,/*+ ALLFIRST_ROWS */ 可以影响优化器模式(虽然它看上去很像注释)。另外,也可以在 SQL 中影响访问路径和执行计划。