`
paldosfan
  • 浏览: 28458 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

【转】 oracle数据库的CBO和RBO优化器

阅读更多
       ORACLE 提供了CBO、RBO两种SQL优化器。CBO在ORACLE7 引入,但在ORACLE8i 中才成熟。ORACLE 已经明确声明在ORACLE9i之后的版本中(ORACLE 10G ),RBO将不再支持。因此选择CBO 是必然的趋势。

CBO和 RBO作为不同的SQL优化器,对SQL语句的执行计划产生重大影响,如果要对现有的应用程序从RBO向CBO移植,则必须充分考虑这些影响,避免SQL 语句性能急剧下降;但是,对新的应用系统,则可以考虑直接使用CBO,在CBO模式下进行SQL语句编写、分析执行计划、性能测试等工作,这需要开发者对 CBO的特性比较熟悉。
以下小结几点在CBO下写SQL语句的注意事项:

1、 RBO自ORACLE 6版以来被采用,有着一套严格的使用规则,只要你按照它去写SQL语句,无论数据表中的内容怎样,也不会影响到你的“执行计划”,也就是说对数据不“敏 感”;CBO计算各种可能“执行计划”的“代价”,即cost,从中选用cost最低的方案,作为实际运行方案。各“执行计划”的cost的计算根据,依 赖于数据表中数据的统计分布,ORACLE数据库本身对该统计分布并不清楚,必须要分析表和相关的索引(使用ANALYZE 命令),才能搜集到CBO所需的数据。

2、使用CBO 时,编写SQL语句时,不必考虑"FROM" 子句后面的表或视图的顺序和"WHERE" 子句后面的条件顺序;ORACLE自7版以来采用的许多新技术都是基于CBO的,如星型连接排列查询,哈希连接查询,函数索引,和并行查询等。

3、一般而言,CBO所选择的“执行计划”都不会比RBO的“执行计划”差,而且相对而言,CBO对程序员的要求没有RBO那么苛刻,节省了程序员为了从多个可能的“执行计划”中选择一个最优的方案而花费的调试时间,但在某些场合下也会存在问题。
较典型的问题有:有时,表明明建有索引,但查询过程显然没有用到相关的索引,导致查询过程耗时漫长,占用资源巨大,这时就需要仔细分析执行计划,找出原 因。例如,可以看连接顺序是否允许使用相关索引。假设表emp的deptno列上有索引,表dept的列deptno上无索引,WHERE语句有 emp.deptno=dept.deptno条件。在做NL连接时,emp做为外表,先被访问,由于连接机制原因,外表的数据访问方式是全表扫描, emp.deptno上的索引显然是用不上,最多在其上做索引全扫描或索引快速全扫描。

4、如果一个语句使用 RBO的执行计划确实比CBO 好,则可以通过加 " rule" 提示,强制使用RBO。

5、使用CBO 时,SQL语句 "FROM" 子句后面的表,必须全部使用ANALYZE 命令分析过,如果"FROM" 子句后面的是视图,则此视图的基础表,也必须全部使用ANALYZE 命令分析过;否则,ORACLE 会在执行此SQL语句之前,自动进行ANALYZE 命令分析,这会极大导致SQL语句执行极其缓慢。

6、使用CBO 时,SQL语句 "FROM" 子句后面的表的个数不宜太多,因为CBO在选择表连接顺序时,会对"FROM" 子句后面的表进行阶乘运算,选择最好的一个连接顺序。假如"FROM" 子句后有6个表,则其可选择的连接顺序就是6*5*4*3*2*1 = 720 种,CBO 选择其中一种,而如果"FROM" 子句后有12个表,则其可选择的连接顺序就是2*11*10*9*8*7*6*5*4*3*2*1= 479001600 种,可以想象从中选择一种,会消耗多少CPU 时间?如果实在是要访问很多表,则最好使用 ORDER 提示,强制使用"FROM" 子句表固定的访问顺序。


7、使用CBO 时,SQL语句中不能引用系统数据字典表或视图,因为系统数据字典表都未被分析过,可能导致极差的“执行计划”。但是不要擅自对数据字典表做分析,否则可能导致死锁,或系统性能严重下降。

8、使用CBO 时,要注意看采用了哪种类型的表连接方式。ORACLE的共有Sort Merge Join(SMJ)、Hash Join(HJ)和Nested Loop Join(NL)。CBO有时会偏重于SMJ 和 HJ,但在OLTP 系统中,NL 一般会更好,因为它高效的使用了索引。
在两张表连接,且内表的目标列上建有索引时,只有Nested Loop才能有效地利用到该索引。SMJ即使相关列上建有索引,最多只能因索引的存在,避免数据排序过程。HJ由于须做HASH运算,索引的存在对数据查询速度几乎没有影响。

9、使用CBO 时,必须保证为表和相关的索引搜集足够的统计数据。对数据经常有增、删、改的表最好定期对表和索引进行分析,可用SQL语句“analyze table xxx compute statistics for all indexes;"ORACLE掌握了充分反映实际的统计数据,才有可能做出正确的选择。

10、使用CBO 时,要注意被索引的字段的值的数据分布,会影响SQL语句的执行计划。例如:表emp,共有一百万行数据,但其中的emp.deptno列,数据只有4种 不同的值,如10、20、30、40。虽然emp数据行有很多,ORACLE缺省认定表中列的值是在所有数据行均匀分布的,也就是说每种deptno值各 有25万数据行与之对应。假设SQL搜索条件DEPTNO=10,利用eptno列上的索引进行数据搜索效率,往往不比全表扫描的高,ORACLE理所当 然对索引“视而不见”,认为该索引的选择性不高。

我们考虑另一种情况,如果一百万数据行实际不是在4种deptno值间平均分配,其中有99万行对应着值10,5000行对应值 20,3000行对应值30,2000行对应值40。在这种数据分布图案中对除值为10外的其它deptno 值搜索时,毫无疑问,如果索引能被应用,那么效率会高出很多。我们可以采用对该索引列进行单独分析,或用analyze语句对该列建立直方图,对该列搜集 足够的统计数据,使ORACLE在搜索选择性较高的值能用上索引。

——————————————————————————————

show parameter optimizer_mode  --看ORACLE处于何种模式,Oracle V7以来缺省的设置应是"choose",即如果对已分析的表查询的话选择CBO,是否选择RBO.如果该参数设置为"rule",则不论表是否分析过, 一概选用RBO,除非在语句中用hint强制.

analyze table xxx compute statistics for all indexes --对表进行分析。

Oracle的优化器有两种优化方式,即基于规则的优化方式(Rule-Based Optimization,简称为RBO)和基于代价的优化方式(Cost-Based Optimization,简称为CBO),在Oracle8及以后的版本,Oracle强列推荐用CBO的方式

RBO方式:优化器在分析SQL语句时,所遵循的是Oracle内部预定的一些规则。比如我们常见的,当一个where子句中的一列有索引时去走索引。

CBO方式:它是看语句的代价(Cost),这里的代价主要指Cpu和内存。优化器在判断是否用这种方式时,主要参照的是表及索引的统计信息。统计信息给 出表的大小、有少行、每行的长度等信息。这些统计信息起初在库内是没有的,是做analyze后才出现的,很多的时侯过期统计信息会令优化器做出一个错误 的执行计划,因些应及时更新这些信息。

注意:走索引不一定就是优的,比如一个表只有两行数据,一次IO就可以完成全表的检索,而此时走索引时则需要两次IO,这时全表扫描(full table scan)是最好

优化模式包括Rule、Choose、First rows、All rows四种方式:

Rule:基于规则的方式。

Choolse:默认的情况下Oracle用的便是这种方式。指的是当一个表或或索引有统计信息,则走CBO的方式,如果表或索引没统计信息,表又不是特别的小,而且相应的列有索引时,那么就走索引,走RBO的方式。

First Rows:它与Choose方式是类似的,所不同的是当一个表有统计信息时,它将是以最快的方式返回查询的最先的几行,从总体上减少了响应时间。

All Rows:也就是我们所说的Cost的方式,当一个表有统计信息时,它将以最快的方式返回表的所有的行,从总体上提高查询的吞吐量。没有统计信息则走RBO的方式。

设定选用哪种优化模式:

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的优化器认为不值得走索引。
分享到:
评论

相关推荐

    CBO,RBO在ORACLE中的应用

    CBO,RBO在ORACLE中的应用

    oracle数据库执行计划

    oracle数据库执行计划文档,描述了cbo,rbo等优化方式,以及数据库执行计划的稳定性

    ORACLE数据库中SQL优化解析

    本文介绍了SQL的执行过程,ORACLE优化器的基本原理,优化器的选择和应用,以及如何建立 和管理索引来提高程序的执行效率。并以实际工作经验介绍了优化工具以及提出对SQL优化的体会。

    ORACLE数据库DBA面试集锦

     在optimizer_mode=choose时,如果表有统计信息(分区表外),优化器将选择CBO,否则选RBO。RBO遵循简单的分级方法学,使用15种级别要点,当接收到查询,优化器将评估使用到的要点数目, 然后选择最佳级别(最少的数量)的...

    性能优化之_Oracle性能优化.ppt

    ORACLE的优化器共有3种: a. RULE (基于规则rbo) b. COST (基于成本cbo) c. CHOOSE (选择性)  设置缺省的优化器,可以通过对init.ora文件中 OPTIMIZER_MODE参数的各种声明,如RULE,COST,CHOOSE,ALL_ROWS,FIRST_ROWS...

    让Oracle跑得更快 Oracle 10g性能分析与优化思路.part2.rar

    4.1 rbo基于规则的优化器 66 4.2 cbo基于成本的优化器 69 第5章 执行计划 85 5.1 cardinality (基数) 85 5.2 sql的执行计划 94 第6章 hint 109 6.1 和优化器相关的hint 115 6.1.1 all_rows和first_rows(cbo) 115 ...

    Oracle优化器 Cardinality基数与Selectivity选择性

    依据所选择执行计划时所用的判断原则,oracle数据库里的优化器又分为RBO和CBO两种。 一、基于规则的优化器。《RBO: Rule-Based Optimization》  Oracle会在代码里事先为各种类型的执行路径定一个等级,一共15个等级...

    ORACLE9i_优化设计与系统调整

    第8章ORACLE数据库系统优化安装 91 §7.1 应用系统环境规划和Oracle系统安装考虑 91 §7.1.1 操作系统安装考虑 91 §7.1.2 Oracle系统安装考虑 92 §7.2 关于创建多个Oracle实例问题 93 §7.3 Oracle系统安装后的...

    让Oracle跑得更快 Oracle 10g性能分析与优化思路.part1.rar

    4.1 rbo基于规则的优化器 66 4.2 cbo基于成本的优化器 69 第5章 执行计划 85 5.1 cardinality (基数) 85 5.2 sql的执行计划 94 第6章 hint 109 6.1 和优化器相关的hint 115 6.1.1 all_rows和first_rows(cbo) 115 ...

    华脉ORACLE高效SQL规则

    1. 基于规则的优化器-- Rule Based (Heuristic) Optimization(简称RBO) 2. 基于代价的优化器 -- Cost Based Optimization(简称CBO) 3. 判断当前数据库使用何种优化器—CHOOSE 4. 如何设定选用哪种优化模式  访问...

    oracle 索引不能使用深入解析

    ORACLEV7以来缺省的设置应是”choose”,即如果对已分析的表查询的话选择CBO,否则选择RBO。如果该参数设为“rule”,则不论表是否分析过,一 概选用RBO,除非在语句中用hint强制。 其次,检查被索引的列或组合索引...

    SQL培训第一期

    结构化查询语言(Structured Query Language)简称SQL,是一种关系数据库查询语言,用于存取数据以及查询、更新和管理关系数据库系统。 1.2 语句结构 1.2.1 数据查询语言(DQL) 对数据库进行的信息查询,select。 ...

Global site tag (gtag.js) - Google Analytics