RBO基于规则的优化器!

优化器:oracle中优化器(Optimizer)是sql分析和执行的优化工具,它负责制订sql的执行计划。oracle的优化器有两种,基于规则的优化器(RBO)和基于代价的优化器(CBO),从oracle 10g开始,RBO已经被测底的废弃拉。

谓词:就是指一个查询中where限制条件。

基于规则的优化器(RBO):就是在优化器里面嵌入若干种规则,执行的sql语句符合哪种规则,则按照哪种规则制订出相应的执行计划。比如:表上有个索引,如果谓词上有索引列的存在,则一定会选择走索引,否则选择走全表扫描。

下面举个例子:


首先创建一个数据分布非常不均匀的表:

SQL> conn /as sysdba
已连接。

SQL> create table u1.t as select 1 id,object_name from dba_objects;

表已创建。

SQL> conn u1/u1
已连接。

SQL> update t set id = 99 where rownum = 1;

已更新 1 行。

SQL> commit;

提交完成。

SQL> create index ind_t on t(id);

索引已创建。

SQL> select id,count(*) from t group by id;

        ID   COUNT(*)
---------- ----------
         1      50600
        99          1

在这个表t中id=99的只有1条记录,剩下的全部是id=1的值。

如果发出这样的两条sql

select * from t where id = 99;
select * from t where id = 1;
在RBO 的年代里面,这两条sql的执行计划是这样的:

SQL> set autotrace traceonly
SQL> select /*+ rule */ * from t where id = 99;


执行计划
----------------------------------------------------------
Plan hash value: 4013845416

---------------------------------------------
| Id  | Operation                   | Name  |
---------------------------------------------
|   0 | SELECT STATEMENT            |       |
|   1 |  TABLE ACCESS BY INDEX ROWID| T     |
|*  2 |   INDEX RANGE SCAN          | IND_T |
---------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("ID"=99)

Note
-----
   - rule based optimizer used (consider using cbo)      --“基于规则的优化器使用(考虑使用CBO)”   这里提示我们当前使用的优化器就是RBO  

统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          3  consistent gets
          0  physical reads
          0  redo size
        473  bytes sent via SQL*Net to client
        400  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL> select /*+ rule */ * from t where id = 1;

已选择50600行。


执行计划
----------------------------------------------------------
Plan hash value: 4013845416

---------------------------------------------
| Id  | Operation                   | Name  |
---------------------------------------------
|   0 | SELECT STATEMENT            |       |
|   1 |  TABLE ACCESS BY INDEX ROWID| T     |
|*  2 |   INDEX RANGE SCAN          | IND_T |
---------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("ID"=1)

Note
-----
   - rule based optimizer used (consider using cbo)


统计信息
----------------------------------------------------------
          1  recursive calls
          0  db block gets
       7044  consistent gets
         98  physical reads
          0  redo size
    1510200  bytes sent via SQL*Net to client
      37503  bytes received via SQL*Net from client
       3375  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
      50600  rows processed
这里set autotrace traceonly同set autotrace on一样,但是不显示查询输出。使用hint  /*+ rule */的方式强制让oracle使用RBO优化器来产生执行计划。可以看见两个查询都使用了索引,但是我们知道,对于id = 1,几乎所有的数据都符合谓词条件,采用全表扫描才是最佳的选择。但是RBO做出了错误的选择。

RBO的情况就是这样,它是一种呆板、过时的优化器,已经在oracle 10g以后的版本中被测底的淘汰掉了。

你可能感兴趣的:(oracle,sql,优化,table,Access,disk)