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

6.7.3 单数据块读操作代价计算演示

原创 由迪 2020-09-29
725

我们通过以下查询语句来演示索引范围扫描和由索引 ROWID 访问表操作的代价估算:
image.png
通过 PLAN_TABLE 还能获得由优化器估算出的 IO 代价和 CPU 指令数:
image.png
获得基本数据
o 获取相关系统参数设置
image.png
索引代价调节比(OPTICA)为 60。优化器采用的数据块大小(OPTBLKSIZE)为 8192。并且未启用缓存统计数据。
o 获取索相关引统计数据
image.png

索引 T_OBJECTS_IDX1 的 B 树高度(BLVL)为 2,叶子节点数(LBLKS)为 209,簇集因子(CLUF) 为 32050,索引记录数(INDROWS)为 47585。
o 获取索引中的字段信息
image.png
以上结果可知该索引建立在 T_OBJECTS(STATUS, OWNER, OBJECT_NAME) 上。
o 获取相关字段的数据类型及在表中位置
根据计算公式,相关字段包括选择字段、索引字段和谓词条件字段。
image.png
o 选择率计算
在查询中,包括了五个谓词条件:
image.png
它们分别组成了索引访问条件、索引过滤条件和表过滤条件。
image.png
我们先按照之前给出的选择率计算方法,结合他们的统计数据及绑定变量值,计算出它们的选择率(过程和前面章节类似,略):
按照由底向上的原则,先计算索引范围扫描的代价。

索引范围扫描代价计算
分别按照上节给出的计算公式计算 IO 代价和 CPU 代价。
o IO 代价
根据公式,我们需要计算出索引访问条件(“STATUS”=‘VALID’ AND “OWNER”>‘DEMO’)的选择率: INDACCSEL = OPSEL[status] * OPSEL[owner]
= 0.9927669*0.9789120
= 0.971831

并将查询得到的统计数据和系统参数设置数值代入公式,得到索引范围扫描的单数据块读数:
#SRDS = BLVL + CEIL(LBLKSINDACCSEL)
= 2 + CEIL(309
0.971831)
= 303

考虑索引代价条件比,得到调整后的 IO 代价值:
IOCOST = ROUND(#SRDS * OPTICA/100)
= ROUND(303 * 60/100)
= 182

结果和执行计划中的估算值一致。

o CPU 代价
依据索引范围扫描的 CPU 总指令数计算公式,需要计算得到索引过滤 CPU 指令数(PICYCLES)。该执行计划中,索引过滤条件为(“OWNER”<>‘SYS’ AND “OBJECT_NAME”<>‘TEST’),且字段 OWNER 也同时出现在了访问条件中,因此 PICYCLES 为:
PICYCLES = TYPOPCYCLES[object_name]+TYPOPCYCLES[owner]OPSEL[object_name]
= 50 + 50
0.9999661
= 99.998305

再将查询得到的数值代入计算公式得到未调节的 CPU 指令数:
#CPUCYCLES = ROUND(ROUND(#SRDS*(0.32OPTBLKSIZE + 3650 + 850)) + ROUND(#SRDSCACHEHIT850) + CEIL(INDROWSINDACCSEL)200 + ROUND(INDROWSINDACCSEL)PICYCLES)
= ROUND(ROUND(303
(0.328192 + 3650 + 850)) + ROUND(3030850) + CEIL(475850.971831)200 + ROUND(475850.971831)*99.998305)
= 16031218

考虑索引代价条件比,得到调整后的 IO 代价值:
#CPUCYCLES = ROUND(16031218 * 60/100)

= 9618731

结果和执行计划中的估算值一致。

由索引 ROWID 访问表代价计算
分别按照上节给出的计算公式计算由索引 ROWID 访问表的 IO 代价和 CPU 代价。
o IO 代价
根据公式,我们需要计算出索引过滤条件的选择率:
INDFLTSEL = INDACCSEL * OPSEL[owner] * OPSEL[object_name]
= 0.9718310.51629990.9999661
= 0.501739

将计算数据和统计数据代入公式,得到单数据块读数:
#SRD= #SRDS[Index Scan] + #SRDS[Access Table]
= 303 + CEIL(32050*0.501739)
= 303 + 16081
= 16384

其中,16081 为访问表的单数据块读次数。

考虑索引代价条件比,得到调整后的 IO 代价值:
IOCOST = ROUND(#SRDS * OPTICA/100)
= ROUND(16384 * 60/100)
= 9830

结果和执行计划中的估算值一致。

o CPU 代价
依据索引范围扫描的 CPU 总指令数计算公式,需要计算得到表数据过滤 CPU 指令数
(FLTCYCLES)。该执行计划中,表数据过滤条件为"OBJECT_ID"<66666,因此 FLTCYCLES 为 50。在索引字段中,STATUS 的位置最大,为 10;选择字段中,SECONDARY 的位置最大,为 13;过
滤条件中,OBJECT_ID 位置最大,为 4.
将统计数据代入计算公式
#CPUCYCLES[Table Access] = ROUND(#SRDS*(0.32OPTBLKSIZE + 3650 + 850)) + ROUND(#SRDSCACHEHIT850) + CEIL(INDROWSINDFLTSEL)130 + CEIL(INDROWSINDFLTSEL)GREATEST(MAXINDCPOS, MAXSELCPOS, MAXFLTCPOS)20 + CEIL(INDROWSINDFLTSELFLTCYCLES)
= ROUND(16081*(0.328192 + 3650 + 850)) + ROUND(160810850) + CEIL(475850.501739)130 + CEIL(475850.501739)GREATEST(10, 13, 4)20 + CEIL(475850.50173950)
= 125025280

加上索引范围扫描的 CPU 指令数,得到当前操作的 CPU 指令数:
#CPUCYCLES = #CPUCYCLES[Table Access] + #CPUCYCLES[Index Scan]
= 16031218 + 125025280
= 141056498

考虑索引代价条件比,得到调整后的 IO 代价值:
#CPUCYCLES = ROUND(#CPUCYCLES * OPTICA/100)
= ROUND(141056498 * 60/100)
= 84633899

o 总代价
结果和执行计划中的估算值一致。在考虑系统统计参数 CPUSPEED(1974.735)和 SREADTIM
(10.381),可以计算的最终代价值。
COST = IOCOST + CPUCOST
= ROUND(16384 * 60/100 + #CPUCYCLES * 60/100 / (CPUSPEED1000SREADTIM))
= 9830.4 + 4.1285
= 9835.5285
实际结果
以下为该例的实际代价结果,与我们的计算结果基本吻合:
image.png
读者可以参考上例的优化器跟踪文件“06_92_10053_IRS(T_OBJECTS_IDX1)_DEMO.trc”。

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

评论