日常记录,开门见山
Oracle优化器规则分为两种
- RBO:一种基于规则(Rule)的优化器
- CBO:一种基于成本(Cost)的优化器
从Oracle 10g后,Oracle已经完全废除了RBO,为什么呢,因为RBO有一个致命的缺陷,它有着一套严格的使用规则,只要你按照它去写SQL语句,无论数据表中的内容怎样,也不会影响到你的“执行计划”,也就是说RBO对数据不“敏感”,是根据ORACLE指定的优先顺序规则,对指定的表进行执行计划的选择,同样的查询结果,两个不同水平的人写出来运行效率会有很大不同。因此对开发人员的技术能力要求过高,对新手不友好。
但温故而知新,可以为师矣,一来毕竟有些客户现场仍然会使用着这一RBO规则,二来只有知道了它,才能明白为什么是现在这个样子,知史以明鉴 查古以至今。
回到这里,上面我们说了优化器规则有两种,因此就要有匹配于这两个优化器规则的优化逻辑模型,目前有五个,分别是
- ALL_ROWS:Oracle默认值,不论是否存在统计信息,都使用CBO优化器,且把CBO的优化目标设定为“最小的成本”
- RULE:不论是否存在统计信息,都将使用RBO优化器来优化SQL
- FIRST_ROWS:CBO尽可能快速的返回结果集的前面少数行记录。不论是否存在统计信息,都使用CBO优化器
- FIRST_ROWS_N:不论是否存在统计信息,都使用CBO优化器,并以最快的速度返回前n行记录,n可以是1,10,100,1000
- CHOOSE:表示SQL语句既可以使用RBO优化器也可以使用CBO优化器,而决定该SQL到底使用哪个优化器的唯一因素是,所访问的对象是否存在统计信息
综上所述,我们如果想使用RBO,就把逻辑模式调为RULE,想使用CBO,就调为ALL_ROWS,当然这个模式也是当前数据库的默认值
那么怎么修改这个值呢,通过修改OPTIMIZER_MODE这一参数值即可完成,同样的,这个修改分为两个等级,分别为
- session:会话级别,仅限于当前会话生效
- system:系统级别生效
修改方式为:
-- 查看当前值
SELECT NAME,VALUE FROM v$parameter WHERE NAME = 'optimizer_mode'
-- 修改为all_rows,如果是会话级别则把system换成session
alter SYSTEM set optimizer_mode=all_rows;
OK,完成
ps:如果真有现场用RBO,那么索引则需要每个地方都用到,否则大数据量会很慢,当然也可通过修改session来临时运行sql