oracle优化器

oralce里优化器有RBO与CBO两种

RBO

RBO基于规则进行,根据固有的规则来选择执行sql的方式
CBO基于成本 选择执行成本最小的一条进行执行,依据是sql语句所涉及的表,索引,列等统计信息

在 10g版本以后rbo已经停止支持,单仍然保留源代码,故仍然可以使用该优化器,但调优手段相对cbo要少一些

RBO将执行计划划分为15个执行等级
1级为rowid访问,执行效率最高。15级为全表扫描,认为执行效率最低

注:即使修改了优化器,或者使用了rule hint oracle一般也不会使用rbo,而仍然强制使用cbo

在SQL中使用hint,则意味着启用CBO,也就是oracle会使用CBO来解析执行含hint的目标SQL

RBO调整手段
1.RBO一条可行的方法就是等价改写目标SQL,如:where条件中对number或者date类型的列假话是哪个0 ,varchar2则加上“|| ”
2.sql中有两条或以上执行路径的等级值相同情况,可以调整在数据字典缓存顺序来影响RBO执行计划的选择
3.对于sql出现的对象的先后顺序调整也可能引起执行计划的改变,关键在于决定随时驱动表,谁是被驱动表

例如:

使用alter session set optimizer_mode=’RULE’ 修改执行优化器为RULE,启用RBO

SQL> alter session set optimizer_mode='RULE';

Session altered

先介绍查看执行计划的两种方法:
1.explain plan for + SQL语句
select * from table(dbms_xplay.display)查看刚刚解析的执行计划

2.set autotrace traceonly explain

SQL>  explain plan for select * from nt where userid='10000000557765' and account='325989' ;

Explained

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 2445682311
---------------------------------------------------
| Id  | Operation                   | Name        |
---------------------------------------------------
|   0 | SELECT STATEMENT            |             |
|   1 |  TABLE ACCESS BY INDEX ROWID| NT          |
|   2 |   AND-EQUAL                 |             |
|*  3 |    INDEX RANGE SCAN         | INX_USERID  |
|*  4 |    INDEX RANGE SCAN         | INX_ACCOUNT |
---------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   3 - access("USERID"=10000000557765)
   4 - access("ACCOUNT"='325989')
Note
-----

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

21 rows selected

可以看到使用了两个索引 INX_USERID,INX_ACCOUNT

如果我们此时不想让表走索引INX_ACCOUNT,那么可以对SQL进行等价修改:

select * from nt where userid='10000000557765' and account+0='325989' ;

SQL> explain plan for select * from nt where userid='10000000557765' and account+0='325989' ;

Explained

SQL> select * from table(dbms_xplan.display)
  2  ;

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 3772635577
--------------------------------------------------
| Id  | Operation                   | Name       |
--------------------------------------------------
|   0 | SELECT STATEMENT            |            |
|*  1 |  TABLE ACCESS BY INDEX ROWID| NT         |
|*  2 |   INDEX RANGE SCAN          | INX_USERID |
--------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter(TO_NUMBER("ACCOUNT")+0=325989)
   2 - access("USERID"=10000000557765)
Note
-----
   - rule based optimizer used (consider using cbo)

19 rows selected

可以查看到只是使用了inx_userid

调整对象的顺序,引起执行计划改变

SQL> explain plan for select * from nt where account='325989' and userid='10000000557765' ;

Explained

SQL> select * from table(dbms_xplan.display)
  2  ;

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 17873495
---------------------------------------------------
| Id  | Operation                   | Name        |
---------------------------------------------------
|   0 | SELECT STATEMENT            |             |
|   1 |  TABLE ACCESS BY INDEX ROWID| NT          |
|   2 |   AND-EQUAL                 |             |
|*  3 |    INDEX RANGE SCAN         | INX_ACCOUNT |
|*  4 |    INDEX RANGE SCAN         | INX_USERID  |
---------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   3 - access("ACCOUNT"='325989')
   4 - access("USERID"=10000000557765)
Note
-----

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

21 rows selected

CBO

CBO基于成本的优化器

cbo生成执行计划会考虑到实际执行对象所涉及的数据量,数据分布情况,网络状态,IO,cpu等资源情况

网络资源一般消耗与使用了dblink的分布式SQL中,但是该种SQL查看执行计划略有特殊

CBO解析目标SQL,首先对sql进行查询转换,转换完成后得到等价改写sql,选择执行路径中成本最小的作为执行计划

cardinality 表示某个具体执行步骤执行结果所包含的记录数量的估算值


SQL> set autotrace traceonly 
SQL> select * from nt;

690622 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 3687718604

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |   690K|   142M|  6132   (1)| 00:01:14 |
|   1 |  TABLE ACCESS FULL| NT   |   690K|   142M|  6132   (1)| 00:01:14 |
--------------------------------------------------------------------------


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
      66775  consistent gets
      22293  physical reads
          0  redo size
  167747687  bytes sent via SQL*Net to client
     506971  bytes received via SQL*Net from client
      46043  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
     690622  rows processed

查看到数据量690K

逻辑读66775 consistent gets
物理读22293 physical reads

SQL> select * from nt where userid='10000000557765';


Execution Plan
----------------------------------------------------------
Plan hash value: 3772635577

------------------------------------------------------------------------------------------
| Id  | Operation                   | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |            |     1 |   217 |     4   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| NT         |     1 |   217 |     4   (0)| 00:00:01 |
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值