首页 > Oracle > oracle 优化 > oracle 全表扫描cost计算!
2013
10-16

oracle 全表扫描cost计算!

虽然在实际工作当中,cost对优化来讲,意义不大,但掌握了解一下还是有帮助的。这篇文章我们先来看一下全表扫描的cost计算。

1. 创建手动管理的表空间,blocksize = 8K

2. 创建测试用户test,默认表空间为test

3.连接到test用户,创建测试表test,并设置pctfree为99,先插入一行数据

4. 修改表,确认一行一个block,再插入测试数据

5. 收集一下test表的统计信息,这时test表的block数为1000个

6. 查看多快读参数,设置为16,如果是16的话,就不用管了

7. 执行需要计算的sql,我们来看一下全表扫描的sql成本

在说明这个公式之前,我先说一下,前面我们收集了表的统计信息,那我们这里人工计算的cost是oracle采用工作量的模式下,如果没有收集统计信息,那oracle采用非工作量的统计方式。

我们首先来看一下公式:成本的计算方式如下:
Cost = (
#SRds * sreadtim +
#MRds * mreadtim +
CPUCycles / cpuspeed
) / sreadtime

#SRds – number of single block reads 单块读个数
#MRds – number of multi block reads  多块读个数
#CPUCyles – number of CPU cycles     CPU时钟周期数

sreadtim – single block read time   单块读耗时(单位milliseconds 毫秒,1000毫秒等于1秒)
mreadtim – multi block read time   多块读耗时(单位milliseconds 毫秒,1000毫秒等于1秒)
cpuspeed – CPU cycles per second     CPU频率(单位MHZ)
mreadtim=ioseektim+db_file_multiblock_count*db_block_size/iotftspeed
sreadtim=ioseektim+db_block_size/iotfrspeed
CPUCycles 等于 PLAN_TABLE里面的CPU_COST—这个ORACLE未解密,无法知道怎么计算的

ps:ssd没有寻道寻址,不能用此公式

8. 我们先来看下cpuspeed的value

9. 再来查询下mreadtim多快读的耗时,我们按照上面的算法执行一下sql计算下

10. 然后在看下单块读耗时

11. 最后我们再来找一下CPUCycles ,等同于PLAN_TABLE里面的CPU_COST

12. 把查找出来的值带入到公式当中计算一下,这里除以1000是换算毫秒的单位。

这里计算出来的结果是219,但是和执行计划看到的220不一致。这是因为有一个隐含参数_tablescan_cost_plus_one造成的结果。

如果这个参数为true,根据描述,那我们在手工计算cost的时候,在table full scan和index fast full scan的时候需要将cost+1才行,可以把这个隐含参数设置为false,这样算出来的结果就和执行计划里面的结果一致了。

最后编辑:
作者:Jerry
一个积极向上的小青年,热衷于分享--Focus on DB,BI,ETL