案例:what’s fuck?CBO居然选择cost值高的

本案例来自北区某客户的一条sql出现了性能问题,在分析过程中发现这是一个非常诡异的sql案例,所以记录下来。如果有遇到过的朋友,欢迎交流。

客户数据库版本11.2.0.4,有一条sql在主库上运行缓慢,但是在ogg同步的一个目标库上执行性能很好,sql优化就太简单了,把目标库上的执行计划outline固定到主库上就好了,优化本身也不是本文的重点,但是在固定的过程中发现了一个诡异的现象。。。

话不多说我们来看看sql文本:

sql文本非常简单,错误的执行计划如下:

主库固定执行计划outline正确的执行计划如下:

错误的执行计划选择了一个错误的索引IDX_HIS_HIS_TERMINALINFOS_SOUR的index skip scan,cost高达215k;而正确的执行计划通过or展开选择了IDX_HIS_HIS_TERMINALINFOS_CURR的index range scan,cost仅为2551。那么问题来了,为何CBO会选择一个cost高的执行计划呢?最常见的原因就是sql本身已经固定了执行计划,但是从sqlhc脚本采集的信息中看到,实际并没有看到有profile/baseline/sqlpatch绑定过该sql。

那么具体到底是怎么回事呢?尝试从10053中寻找答案。

首先介绍一下or-Expansion,or-Expansion是一种非启发式查询转换,也就是说cbo评估转换后的成本要低于转换前的成本,才会执行该查询转换。这里特别要注意的是,or-Expansion会对每个OR-branching进行评估,如果有其中一个OR-branching的转换成本高于转换前的成本时,则会终止后面的OR-branching评估,CBO就认为该sql不能进行or-Expansion。

该sql总共有2个or,那么应该会有3个OR-branching,但实际10053中只出现了2个,说明在做第二个OR-branching成本评估时,发现该分支or展开成本过高。

第一个OR-branching评估如下,cost计算以及索引选择都是正确的。

第二个OR-branching评估就出现了诡异的现象

诡异点:

  • CBO对cost的计算完全正确,但是选择发生了错误。并没有选择cost为1320.42的IDX_HIS_HIS_TERMINALINFOS_CURR(range scan),而去选择了一个cost为215449.05的IDX_HIS_HIS_TERMINALINFOS_SOUR(skip scan)。
  • Best:: AccessPath: IndexRange,但实际选择的是SkipScan。

并且认为or展开成本过高终止了评估,并且认为该sql不进行or展开

如果观察仔细的话,可以发现实际计算的cost都打了个1折,如resc_io: 2153610.00(IO_COST) resc_cpu: 32478849773(CPU_COST),而实际cost仅为Cost: 215449.05,这明显是optimizer_index_cost_adj参数的作用效果,从执行计划outline中可以看到OPT_PARAM(‘optimizer_index_cost_adj’ 10),确实是会把索引访问成本乘以0.1得到实际成本。

当发现该环境设置了optimizer_index_cost_adj为10之后,我认为这并不是CBO选择cost高的执行计划的原因,因为无论是index range scan还是index skip scan,都会受到optimizer_index_cost_adj的作用去乘以0.1的系数,并且cost计算是完全没问题的,只是选择了一个cost高的访问路径。

但是打脸来的就是那么快,经过同事的测试验证,对于该案例的sql来说optimizer_index_cost_adj设置高于40时,CBO选择会完全正确。这就很不科学了。。。

通过10053查看之前评估错误的OR-branching,这次它又行了。。。百思不得其解呀。。。

尝试过调整optimizer_features_enable到8i也是正常的,所以想通过遍历fix_control的方式,看看能不能找到是为了修复哪个bug导致的,很不幸也没有找到。遍历fix_control的脚本使用的anbob大神的脚本,脚本分享如下:

查看mos也没有找到匹配的bug,这种非常少见的问题和场景也没必要太过纠结,但是还是有必要记录一下。因为这个案例给了我们一个启发,optimizer_index_cost_adj,包括所有的优化器参数,谨慎调整,严格测试,理论是理论,但是总有意外,因为不知道又会触发什么奇怪的问题。

如果有兴趣的朋友不妨提个sr看看原厂的研发团队是否能解释这个问题。

 

此条目发表在Oralce performance分类目录,贴了标签。将固定链接加入收藏夹。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注