oracle执行计划(4)--COST成本全表扫描成本

转自 http://blog.csdn.net/zengmuansha/article/details/7489822

公式:    
According to the CPU costing model:
Cost = (
#SRds * sreadtim +
#MRds * mreadtim +~~~~~~~~~~~~~~~~~~~~~~~~~~~~
来自于cost-based 
oracle书中
#CPUCycles / cpuspeed
) / sreadtim
where
#SRDs - number of single block reads -–单块读取次数
#MRDs - number of multi block reads –-多块读取次数
#CPUCycles - number of CPU Cycles  --目前执行计划中的CPU_COST
sreadtim - single block read time  --单块读取时间
mreadtim - multi block read time  --多块读取时间
cpuspeed - CPU cycles per second  --每秒执行的标准操作

 

SQL> select * from V$version;

BANNER

----------------------------------------------------------------

Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bi

PL/SQL Release 10.2.0.3.0 - Production

CORE 10.2.0.3.0    Production

TNS for Linux: Version 10.2.0.3.0 - Production

NLSRTL Version 10.2.0.3.0 - Production

建立测试表

SQL> create table t1 (a int);

Table created

Sql>

declare
   
begin
   for
 i in 1..10000
 loop
    
insert into t1 values(i);
   end loop;
end;
/

SQL>COMMIT;  

SQL> select blocks from user_tables where table_name='T1';

    BLOCKS

----------

SQL> select count(*) from t1;

  COUNT(*)

----------

     10000

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

PL/SQL procedure successfully completed

SQL> select blocks from user_tables where table_name='T1';

    BLOCKS

----------

        20

SQL>  show parameter db_block_size

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

db_block_size                        integer     8192

SQL> show parameter db_file_mu

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

db_file_multiblock_read_count        integer     16

 

SQL> set autotrace traceonly

SQL> select * from t1;

已选择10000行。

已用时间:  00: 00: 00.21

执行计划

----------------------------------------------------------

Plan hash value: 3617692013

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

 

SQL> select pname,pval1 from sys.aux_stats$ where sname='SYSSTATS_MAIN';

 

PNAME                               PVAL1
------------------------------ ----------
CPUSPEEDNW                     713.978494
IOSEEKTIM                              10
IOTFRSPEED                           4096
SREADTIM                           21.046
MREADTIM                           45.384
CPUSPEED                             1042
MBRC                                   12
MAXTHR                           54754304
SLAVETHR                       

 

9 rows selected

 

上面的系统信息需要用SYS帐号运行

 EXECUTE DBMS_STATS.GATHER_SYSTEM_STATS(‘start);

……. –运行一些超长查询 全表扫描

EXECUTE DBMS_STATS.GATHER_SYSTEM_STATS(‘stop’);

MRDS= BLOCKS/ MBRC=20/12=1.6667

 

如果没有统计信息采用默认计算公式方法:
MBRC=db_file_multiblock_read_count=16
MRDS=20/16=1.25
sreadtim=IOSEEKTIM+db_block_size/IOTFRSPEED=10+8192/4096=12
mreadtime=IOSEEKTIM+db_file_multiblock_read_count*db_block_size/IOTFRSPEED=10+16*8192/4096=42

 

转换下公式

Cost = (#SRds +#MRds * mreadtim / sreadtim +(#CPUCycles / cpuspeed) / sreadtim)

=(0+MRDS*45.384/21.046+(CPUCycles/713.978494)/21.046)

=(1.6667*45.384/21.046)+(1631329/713.978494/21.046)

=3.594+108.564 ????

 

因为sreadtim是millisecond 毫秒级 换成微妙参与CPU部分运算

=(1631329/713.978494/21046)

=0.108564

=>

=3.594+0.108564=3.702564

由于 _table_scan_cost_plus_one  = true   所以加1

3.702564+1=4.702564

Ceil(4.702564)=5   --四舍五入函数

全表扫描最终成本公式:

Cost = ceil((SRds +MRds * mreadtim / sreadtim +(CPU_COST /cpuspeednw)/sreadtim*1000)+1)

 

默认公式:

= ceil((0 +1.25 * 42 / 12 +(1631329/713.978494)/12*1000)+1)

=ceil((4.375+2284.84333/12000)+1)

=ceil((4.375+0.19040)+1)

=ceil(5.5654)

=6

偏大了!

posted @ 2014-01-29 01:11  princessd8251  阅读(1210)  评论(0编辑  收藏  举报