一 代价模型
要量化执行计划的每一个操作的代价,必须建立一个统一的分析模型。在这个模型内,各种操作的代价可以被量化并且有统一的估算单位。ORACLE数据库中,SQL语句执行消耗的主要是CPU和IO。正确计算CPU和IO的代价,就可以正确估算真个SQL的成本代价。
ORACLE中存在两种代价模型: IO代价模型 和 CPU代价模型。
通过优化器的初始化参数_OPTIMIZER_COST_MODEL控制采取哪种模型,有四个值:
IO : IO 代价模型,仅考虑IO 代价,只考虑IO 次数而不考虑时间因素。
CPU :CPU代价模型,分别计算IO代价和CPU代价,通过系统统计数据计算出CPU代价向IO代价转换的因子CPU_TO_IO), 将CPU代价转换成IO代价。如果系统统计数据不可以,将使用系统统计数据默认值计算CPU_TO_IO。
FIXED :与CPU代价模型一样,分别计算IO和CPU代价,使用系统内部固定值将CPU代价转换为IO代价。
如果存在系统统计数据,CPUSPEED 采用固定值100 000,IOSEEKTIM 和IOTFRSEED 采用系统值,计算CPU_TO_IO.
如果不存在系统统计数据,CPUSPEED 采用固定值100 000,IOSEEKTIM 和IOTFRSEED 采用默认值,计算 CPU_TO_IO.
CHOOSE(默认值) :如果存在可用的系统统计数据则用CPU代价模型,否则用IO代价模型。
由于系统在启动时候,就会以NOWORKLOAD 模式初始化系统统计数据,因此,在默认情况下,优化器采用CPU代价模型。
二 基本代价计算公式
1 在代价模型中,所有的代价都转换成单数据块读的单次代价,即单块读的次数(#SRDS)。
2 查询过程中,存在四种类型IO ,单数据块读SRD,多数据块读MRD,直数据块读DRD,直数据块写DWT;
IOCOST = SRDCOST+MRDCOST+DRDCOST+DWTCOST
直接数据块操作,省略将拷贝数据块到SGA过程,但由于磁盘读写速度和内存读写速度差异很大,因此可以忽略复 制 到SGA所消化的代价,将直接数据块操作转换为单数据块操作,或者多数据块操作,因为它们代价大致相当。
IOCOST = SRDCOST+MRDCOST
3 IO 的代价由IO次数 乘以每次IO时间 构成,IO 时间是由寻址时间和传输时间构成。单块读和多块读的寻址时 间是一样的,差异在传输时间。因此将多块读代价转换成单块读,通过计算出两个传输时间的比值就可以进行
换算,计算出相对于的单块读的次数(#SRDS)。
MRDCOST = #MRDS * (MREADTIM/SREADTIM)
4 由于查询语句在读取和过滤数据过程中,还会进行对字段选取,字段数据与谓词条件的比较等,请求CPU执行
不同的指令。每种操作根据其处理工作量不同请求CPU执行不同的指令,称之为CPU转数(#CPUCYCLES)。
CPU转数(#CPUCYCLES)可以简单理解为CPU执行不同的指令合计的总工作量。这些CPU消耗,通过CPU_TO_IO, 转换给相对应的IO消耗,就可以计算相对应的IO 代价。
CPUCOST=#CPUCYCLES/CPU_TO_IO
5 CPU 的处理速度是按照每秒钟执行多少指令来衡量的,即CPU速度(CPUSEED) . #CPUCYCLES/CPUSEED ,可以计算 出完成全部CPU指令所需要的总时间。#CPUCYCLES/CPUSEED 再除以 单数据块读的时间 SREADTIM ,就可以得 到单数据块 的次数(#SRDS)。
CPUCOST=#CPUCYCLES/CPU_TO_IO = #CPUCYCLES/(CPUSEED*SREADTIM)
IO 代价模型计算公式
COST = IOCOST =#SRDS + #MRDS
IO代价模型忽略时间因素,仅计算单块读次数(#SRDS)和多块读次数(#MRDS)
CPU代价模型计算公式
COST=CPUCOST+IOCOST
CPUCOST = #CPUCYCLES/CPU_TO_IO
= #CPUCYCLES/(CPUSEED*SREADTIM)
IOCOST= SRDCOST+MRDCOST+DRDCOST+DWTCOST
= #SRDS + #MRDS*(MREADTIM/SREADTIM)
COST = #CPUCYCLES/(CPUSEED*SREADTIM) + #SRDS + #MRDS*(MREADTIM/SREADTIM)
= (#CPUCYCLES/CPUSEED +#SRDS*SREADTIM + #MRDS*MREADTIM) / SREADTIM
注意:估算代价都是整数,是由于参数“_optimizer_ceil_cost” 控制,默认值为TRUE,使用CEIL函数将计算过程中的小数去掉。
本文整理学习自《Oracle 高性能SQL引擎剖析》,作者:黄玮。