暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

6.5.4 执行计划中其他数据的计算

原创 由迪 2020-09-25
533

在执行计划中,还有一些其他数据是在估算代价的过程中同时计算出来的,包括记录数
(Rows)、字节数(Bytes)和运行时间(Time)。
记录数(Rows)
记录数就是我们前面提到的选择数据记录数(SELROWS)。全表扫描操作中,由最终选择率
(SEL)和表的数据记录数(ALLROWS)决定:
SELROWS = ROUND(ALLROWSSEL,0)
字节数(Bytes)
字节数则由记录数和被选择及过滤的字段平均长度共同决定。其中,字段平均长度属于字段统 计数据。
Bytes = SELROWS * (COLLEN1 + COLLEN2 + … + COLLENn )
其中,COLLENi 为被选择及过滤的字段的平均长度。
运行时间(Time)
由于估算出的代价统一为单数据块读的 IO 代价,因此,运行时间则是总的代价乘以单次单数据块读时间(SREADTIM):
Time = CEIL(COST
SREADTIM/1000)
计算出的结果以秒为单位。

6.5.5 全表扫描代价估算示例演算
我们以以下脚本中的查询语句为例,计算出优化器在 CPU 代价模型下估算的全表扫描代价值。
注意,由于环境不同,读者在自己的数据库上运行演示脚本,可能会得到不同的数据。读者可以参考演示过程重新计算。
image.png

获得基本数据
在代价计算过程中,用于代价计算的基本数值就是系统和对象的统计数据,而在选择计算公式 和计算因子时,则受到优化器参数的影响。要计算执行计划代价,就需要先获得这些数据。

优化器系统参数
影响优化器的系统参数非常多,但其中大多数都属于隐含参数,并不建议调整。在 10053 事件的跟踪内容中,列出了全部相关参数。我们这里仅找出部分影响全表扫描代价计算的参数值:
image.png

系统统计数据计算
要获得系统统计数据,先要确认当前的统计数据是哪个模式下的:仅当 CPUSPEED、SREADTIM、
MREADTIM 和 MBRC 都被收集到数据时,采用 WORKLOAD 模式下的统计数据,否则为NOWORKLOAD。
image.png
image.png
经过检查,确认当前系统统计数据是在 NOWORKLOAD 模式下收集的。CPU 代价模型中,MBRC 采用参数"db_file_multiblock_read_count"设置,然后再根据其他统计数据计算出 SREADTIM 和
MREADTIM。
SREADTIM = IOSEEKTIM+OPTBLKSIZ/IOTFRSPEED = 10.381 MREADTIM = IOSEEKTIM+MBRC*OPTBLKSIZ/IOTFRSPEED = 40.381
表统计数据
在全表扫描中,用于代价估算的表统计数据包括数据块数(BLKS)、数据记录数(ALLROWS)、缓存数据块数(CACHEDBLK)和缓存命中率(CACHEHIT):
image.png

字段统计数据
计算 CPU 代价时需要获取相关字段的元数据和统计数据。在我们的查询语句中,被选择的字段为 OWNER、SUBOBJECT_NAME 和 CREATED,而过滤字段为 OBJECT_ID、OWNER 和 OBJECT_NAME。

image.png

提示:通过视图 dba_tab_columns 可以同时查找出字段的元数据和统计数据。

IO 部分代价计算
确认了参数数值、系统统计数据和表统计数据后,我们就可以按照之前给出的公式计算出 IO
部分的代价。

IOCOST = CEIL(CEIL(BLKS/MBRC))(IOSEEKTIM+MBRCOPTBLKSIZ/IOTFRSPEED)/(IOSEEKTIM+OPTBLKSIZ/IOTFRSPEE D)) + 1
= CEIL(CEIL(830/16)(8.381+168192/4096)/(8.381+8192/4096)) + 1
= 204

计算得到 IO 代价为 204。和跟踪内容中一致:
image.png
选择率计算
由于数据记录过滤的指令数与过滤条件的选择率相关,我们需要计算出过滤条件的选择率。语 句中的过滤条件为:

cobject_id < 1000 or (owner in (‘DEMO’, ‘OUTLN’) or object_name like ‘T%’)

先逐个针对单个过滤条件计算,

o OPSEL[cobject_id]
cobject_id 的柱状图类型为"HEIGHT BALANCED",按照选择率计算公式,对其做<过滤时,计算式为:
OPSEL[cobject_id] = (BEN[n-1]+POPADJ+RANGEADJ)/BKTNUM*DECODE(COLNB=Y,1,NNV/ALLROWS)

匹配值(1000)落入分组 0~分组 1 之间:

得到:
o BEN[n-1] = 1;
o 分组数(BKTNUM)为 75;
o 分组不存在流行数值,因此 POPADJ = 0;
o RANGEADJ = (1000 - 706)/(1357 - 706) = 0.451612903
o cobject_id 为非空字段,DECODE(COLNB=Y,1,NNV/ALLROWS) = 1;

因此该过滤条件的选择率为:

OPSEL[cobject_id] = (BEN[n-1]+POPADJ+RANGEADJ)/BKTNUMDECODE(COLNB=Y,1,NNV/ALLROWS)
= (1 + 0 + 0.451612903)/75
1
= 0.019354839

o OPSEL[owner]
owner 的柱状图类型为“FREQUENCY”,按照选择率计算公式,对其做 IN 过滤时,计算式为:
OPSEL[owner] = (DBEN[1]+DBEN[2]+…+DBEN[i])/MAXBEN*DECODE(COLNB=Y,1,NNV/ALLROWS)

匹配值(‘DEMO’)命中分组 3,匹配值(‘OUTLN’)命中分组 3:
image.png
得到:
o DBEN[1] = 103 - 52;DBEN[2] = 154 - 153;

o 最大分组结束点数(MAXBEN)为 4908;
o cobject_id 为非空字段,DECODE(COLNB=Y,1,NNV/ALLROWS) = 1;

因此该过滤条件的选择率为:
OPSEL[owner] = ((DBEN[1]+DBEN[2]+…+DBEN[i])/MAXBENDECODE(COLNB=Y,1,NNV/ALLROWS)
= ((103-52) + (154-153))/4908
1
= 0.010594947

o OPSEL[object_name]
object_name 的柱状图类型为"HEIGHT BALANCED",按照选择率计算公式,对其做 LIKE 过滤时, 计算式为:
OPSEL[object_name] = (BEN[h]- BEN[l]+POPADJ+RANGEADJ)/BKTNUM*DECODE(COLNB=Y,1,NNV/ALLROWS)

匹配值的最大、最小值都落入分组 54 中:
image.png
得到:
o BEN[h] = 54,BEN[l] = 54;
o 分组数(BKTNUM)为 75;
o 分组不存在流行数值,因此 POPADJ = 0;
o RANGEADJ = (441345232975460-436152936116926)/(443014200323538-432772379159649)
= 0.506970076
o cobject_name 为非空字段,DECODE(COLNB=Y,1,NNV/ALLROWS) = 1;

因此该过滤条件的选择率为:
OPSEL[object_name] = (BEN[h]- BEN[l]+POPADJ+RANGEADJ)/BKTNUMDECODE(COLNB=Y,1,NNV/ALLROWS)
= (54 - 54 + 0 + 0.506970076)/75
1
= 0.006759601
o 组合过滤条件的选择率计算
计算组合过滤条件的选择率时,按照过滤条件的优先级计算。

EXPOPSEL[owner AND object_name]
先计算组合过滤条件 “owner in (‘DEMO’, ‘OUTLN’) AND object_name like ‘T%’”,根据组合表达式计算公式,
EXPOPSEL[owner, object_name] = OPSEL[owner] * OPSEL[object_name]
= 0.010594947*0.006759601
= 0.000071618

EXPOPSEL[object_id OR (owner AND object_name)]
在计算整个组合过滤条件,计算表达式为:
SEL = EXPOPSEL[object_id OR (owner AND object_name)]
= OPSEL[object_id] + EXPOPSEL[owner, object_name] – OPSEL[object_id]EXPOPSEL[owner, object_name]
= 0.019354839 + 0.000071618 - 0.019354839
0.000071618
= 0.019425071
o 选择数据记录数
有了选择率以后,就可以根据公式 ALLROWSSEL 得到选择数据记录数:
SELROWS = ROUND(ALLROWS
SEL)
= ROUND(0.019425071*47585)
= 924

这和执行计划中的结果一致:
image.png

CPU 代价计算
按照 CPU 的代价计算公式,我们需要先逐个计算出各种处理的平均 CPU 指令数。
读取磁盘数据块指令数
RDCYCLES = 0.32OPTBLKSIZE + 3650
= 0.32
8192 + 3650
= 6271.44
读取内存数据块指令数
RBCYCLES = 850
从数据块获取数据记录指令数
GRCYCLES = 130
o 过滤操作指令数

同样,对于组合过滤条件,我们需要逐个计算过滤操作指令数。

TYPOPCYCLES[object_id]
object_id 为 NUMBER 类型数据,对其进行<匹配时,指令数为,
TYPOPCYCLES[object_id] = TYPCYCLES
= 150

TYPOPCYCLES[owner]
owner 为 VARCHAR2 类型数据,对其进行 IN 匹配时,指令数为,
TYPOPCYCLES[owner] = TYPCYCLES*(1+(1-MAX(OPSEL[1],OPSEL[2])))
= 50*(1+(1-MAX((103-52)/4908,(154-153)/4908)))
= 99.4804401

TYPOPCYCLES[object_name]
owner 为 VARCHAR2 类型数据,对其进行 LIKE 匹配时,指令数为,
TYPOPCYCLES[object_name] = TYPCYCLES + 50
= 50 + 50
= 100

TYPOPCYCLES[owner and object_name]
owner 与 object_name 的组合条件的指令数为:
TYPOPCYCLES[owner and object_name] = LEAST((TYPOPCYCLES[a]+TYPOPCYCLES[b]OPSEL[a]), (TYPOPCYCLES[b]+TYPOPCYCLES[a]OPSEL[b]))
= LEAST(99.4804401+100
0.010594947, 100+99.4804401
0.006759601)
= LEAST(100.539935, 100.672448)
= 100.539935

TYPOPCYCLES[object_id or (owner and object_name)]
最终的条件匹配指令数为:
FLTCYCLES = TYPOPCYCLES[object_id or (owner and object_name)]
= LEAST((TYPOPCYCLES[a]+TYPOPCYCLES[b](1-OPSEL[a])), (TYPOPCYCLES[b]+TYPOPCYCLES[a](1-OPSEL[b])))
= LEAST(50+100.539935*(1-0.019354839), 100.539935+50*(1-0.000071618))
= LEAST(148.594001, 150.536354)
= 148.594001
o 选择字段指令数
在我们的语句中,被选择的字段为 OWNER、SUBOBJECT_NAME 和 CREATED,从前面获取的字段元数据信息可以知道,最大位置字段为 CREATED,MAXSELCPOS 为 7;过滤字段为 object_id、
owner 和 object_name,object_id 位置最大,MAXFLTCPOS 为 4。因此从数据记录中获取字段指令数的计算为:
GCCYCLES = (GREATEST(1, MAXFLTCPOS) + SEL * GREATEST(0, MAXSELCPOS - MAXFLTCPOS))20
= (GREATEST(1, 4) + 0.019425071 * GREATEST(0, 7 - 4))20
= 81.1655043
o CPU 总指令数
CPU 总指令数计算公式中的所有参数都已经得到,我们可以计算出该值:
#CPUCYCLES = (#BLKS-CACHEBLK)
(0.32
OPTBLKSIZE + 3650) + #BLKS850 + ALLROWS130 + ALLROWS*( GREATEST(1, MAXFLTCPOS) + SELGREATEST(0, MAXSELCPOS - MAXFLTCPOS) )20 + ALLROWSFLTCYCLES
= (830-0)6271.44 + 830850 + 47585
130 + 47585420+ROUND(475850.019425071,0)320 + 47585148.594001

= 23029930.7
≈ 23029931

这个计算结果和实际结果一致:
image.png
读者可以参考上例的优化器跟踪文件“06_91_10053_FTS(T_Objects)_demo.trc”。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论