oracle实验记录 (predicate对cpu cost的影响)


理解谓词对cpu cost的影响
这个实验脚本来自cost-based oracle,动手实验一次加深印象 

SQL> create table t1(
  2  v1,
  3  n1,
  4  n2
  5  )
  6  as
  7  select
  8  to_char(mod(rownum,20)),
  9  rownum,
 10  mod(rownum,20)
 11  from
 12  all_objects
 13  where
 14  rownum <= 3000
 15  ;

表已创建。

SQL> select count(distinct v1) from t1;

COUNT(DISTINCTV1)
-----------------
               20~~~~~~~~~~~~~~~~~~~~V1 有20个不同值 char类 ,每个数对应150行

SQL> select count(distinct n1) from t1;

COUNT(DISTINCTN1)
-----------------
             3000~~~~~~~~~~~~~~~~~~~~~N1 有3000个不同值 NUMBER类 表示 是唯一的

SQL> select count(distinct n2) from t1;

COUNT(DISTINCTN2)
-----------------
               20~~~~~~~~~~~~~~~~~~~~N2 有20个不同值 NUMBER类 ,每个数对应150行

总共3000 rows


下面4个查询中 前3个使用+ ordered_predicates HINTS 强制按所写的predication顺序 从左到右
最后一个 让CBO优化器自己考虑 注意

  _pred_move_around                   = true (predication 移动 oracle自动排序predication)

  _optimizer_cost_model               = choose(基本使用CPU_COSTING 而不使用8I 的传统计算(只算IO))


SQL> exec dbms_stats.gather_table_stats('SYS','T1');

PL/SQL 过程已成功完成。

SQL> set autotrace traceonly
SQL> alter session set events '10053 trace name context forever';

会话已更改。


SQL> ed
已写入 file afiedt.buf

  1  select
  2  /*+ ordered_predicates */
  3  v1, n2, n1
  4  from
  5  t1
  6  where
  7  v1 = 1
  8  and n2 = 18
  9* and n1 = 998
 10  /

未选定行


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

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |     9 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| T1   |     1 |     9 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

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

   1 - filter(TO_NUMBER("V1")=1 AND "N2"=18 AND "N1"=998)

 


SQL> ed
已写入 file afiedt.buf

  1  select
  2  /*+ordered_predicates */
  3  v1, n2, n1
  4  from
  5  t1
  6  where
  7  n1 = 998
  8  and n2 = 18
  9* and v1 = 1
SQL> /

未选定行


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

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |     9 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| T1   |     1 |     9 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

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

   1 - filter("N1"=998 AND "N2"=18 AND TO_NUMBER("V1")=1)

 


SQL> ed
已写入 file afiedt.buf

  1  select
  2  /*+ ordered_predicates */
  3  v1, n2, n1
  4  from
  5  t1
  6  where
  7  v1 = '1'
  8  and n2 = 18
  9* and n1 = 998
SQL> /

未选定行


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

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |     9 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| T1   |     1 |     9 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

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

   1 - filter("V1"='1' AND "N2"=18 AND "N1"=998)

 

SQL> ed
已写入 file afiedt.buf

  1  select
  2  v1, n2, n1
  3  from
  4  t1
  5  where
  6  v1 = 1
  7  and n2 = 18
  8* and n1 = 998
SQL> /

未选定行


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

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |     9 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| T1   |     1 |     9 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

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

   1 - filter("N1"=998 AND "N2"=18 AND TO_NUMBER("V1")=1)

 


看TRACE

使用
predication  顺序- filter(TO_NUMBER("V1")=1 AND "N2"=18 AND "N1"=998)

select
/*+ ordered_predicates */
v1, n2, n1
from
t1
where
v1 = 1
and n2 = 18
and n1 = 998

 


  Access Path: TableScan
    Cost:  3.25  Resp: 3.25  Degree: 0
      Cost_io: 3.00  Cost_cpu: 1070604****************
      Resp_io: 3.00  Resp_cpu: 1070604
  Best:: AccessPath: TableScan
         Cost: 3.25  Degree: 1  Resp: 3.25  Card: 0.00  Bytes: 0

分析:总共3000行中oracle首先对v1 = 1 进行了3000次转换(to_number) 又在表里3000行中 让 V1与一个数值进行比较产生了 150行(3000/20) CPU进行了3000次比较操作
又在这150行中 n2与一个数值比较 产生8行(150/20) CPU进行150次比较操作, 最后在这8行中 N1与一个数值比较(N1 唯一) CPU进行8次比较操作,CPU一共进行了 3158次数值比较

+3000次转换操作

 

****************

使用
predication  顺序- filter("N1"=998 AND "N2"=18 AND TO_NUMBER("V1")=1)

select
/*+ordered_predicates */
v1, n2, n1
from
t1
where
n1 = 998
and n2 = 18
and v1 = 1


Access Path: TableScan
    Cost:  3.18  Resp: 3.18  Degree: 0
      Cost_io: 3.00  Cost_cpu: 762786************
      Resp_io: 3.00  Resp_cpu: 762786
  Best:: AccessPath: TableScan
         Cost: 3.18  Degree: 1  Resp: 3.18  Card: 0.00  Bytes: 0

分析:总共3000行中oracle 让N1与一个数值 进行了3000次比较 产生 1行(3000/3000) CPU进行3000次比较操作 ,对这一行 N2与一个数比较一次 产生1行 CPU进行了1次比较操作,

对这一行 V1与一个数比较一次CPU进行1次比较操作, 且V1转换一次
所以为3002次比较操作+1次转换

这个是最节约CPU成本的

******************************
使用
predication  顺序- filter("V1"='1' AND "N2"=18 AND "N1"=998)
select
/*+ ordered_predicates */
v1, n2, n1
from
t1
where
v1 = '1'
and n2 = 18
and n1 = 998

  Access Path: TableScan
    Cost:  3.18  Resp: 3.18  Degree: 0
      Cost_io: 3.00  Cost_cpu: 770604**********************
      Resp_io: 3.00  Resp_cpu: 770604
  Best:: AccessPath: TableScan
         Cost: 3.18  Degree: 1  Resp: 3.18  Card: 0.00  Bytes: 0
分析:总共3000行中 oracle  让V1与一个值比较 产生150行 CPU进行了3000次比较操作,150行中 让N2与一个值比较cpu进行比较操作150次产生8行,又在这8行中 让N1与一个数值比

较 CPU比较8次产生1行
注意没有进行转换3000次对V1
所以ORACLE CPU进行了3158次比较操作  

SQL> select 1070604-770604 from dual;

1070604-770604
--------------
        300000

3000次转换 CPU COST 多了 300000 这样可以得出 一次to_number隐式转换 需要100次 CPU操作(300000/3000=100)

**************************
oracle optimizer自动选  顺序- filter("N1"=998 AND "N2"=18 AND TO_NUMBER("V1")=1)

select
v1, n2, n1
from
t1
where
v1 = 1
and n2 = 18
and n1 = 998
Access Path: TableScan
    Cost:  3.18  Resp: 3.18  Degree: 0
      Cost_io: 3.00  Cost_cpu: 762786*********************
      Resp_io: 3.00  Resp_cpu: 762786
  Best:: AccessPath: TableScan
         Cost: 3.18  Degree: 1  Resp: 3.18  Card: 0.00  Bytes: 0


分析:最后这个ORACLE 采用了第2个SELECT 所使用的PREDICATION 顺序 没有按照 指定的顺序 oracle进行COST 评估后采用了这个顺序
  _pred_move_around                   = true 由于这个参数 让ORACLE自动对PREDICATION 选择合适的顺序


SQL> alter system set "_pred_move_around"=false;************实验改下

系统已更改。
SQL> set autotrace traceonly
SQL> alter session set events '10053 trace name context forever';

会话已更改。

SQL>  select
  2   v1, n2, n1
  3   from
  4   t1
  5   where
  6   v1 = 1
  7   and n2 = 18
  8   and n1 = 998
  9  /

未选定行


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

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |     9 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| T1   |     1 |     9 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

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

   1 - filter("N1"=998 AND "N2"=18 AND TO_NUMBER("V1")=1)~~~~~~~~~~~~~~~~雪特还是自己变化了

 

_pred_move_around              FALSE                     FALSE     FALSE      FALSE

enables predicate move-around

10GR2中好象没起作用

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12020513/viewspace-613681/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/12020513/viewspace-613681/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值