• Oracle优化器模式不同导致索引失效


           最近测试过程中碰到一个诡异的问题:增加相同的索引,执行相同的查询语句,在A数据库查询耗时缩短,可在B数据库查询耗时几乎不变。这让我一度怀疑B数据库有毒,然而重启大法也没能解决。最后确认问题是由于oracle优化器模式不同,导致不规范索引造成的索引失效。

           下面详细看看这个例子。

           增加索引语句如下:

    CREATE INDEX idx_datetime ON my_Table(init_date,curr_date,update_time) TABLESPACE MY_IDX    

           这个语句增加了由三个字段组成的索引。相同的索引,在A数据库有效,而在B数据库无效,怀疑是数据库优化器的模式不同。

           使用以下语句查看数据库优化器模式。

    Show parameter opti;

           其中,A数据库的模式是ALL_ROWS。

           B数据库的优化器模式是RULE。

           Oracle的优化器有两种,基于规则的优化器(RBO)和基于代价的优化器(CBO)。上述例子中的ALL_ROWS是基于代价的优化器CBO,RULE是基于规则的优化器RBO。

           RBO有着一套严格的使用规则,只要你按照它去写SQL语句,无论数据表中的内容怎样,也不会影响到你的“执行计划”,也就是说RBO对数据不“敏感”;它根据ORACLE指定的优先顺序规则,对指定的表进行执行计划的选择。在RBO中,SQL的写法往往会影响执行计划。上述例子中,数据库B用的是RBO优化器。我们来看看用于测试的查询语句。

    1 select count(*) as count_n  
    2        from my_Table  
    3        where ((curr_date = 20200525 and update_time <= 153000)  
    4        or (curr_date = (select max(a.init_date) from your_Table a where a.init_date < 20200525) and update_time > 153000)  
    5        or (curr_date > (select max(a.init_date) from your_Table a where a.init_date < 20200525) and curr_date < 20200525))  

           在这个查询语句中,实际用于过滤my_Table表的是curr_date和update_time两个字段,而新增索引中有三个字段[init_date, curr_date, update_time],多了一个init_date字段,导致RBO模式下判定第一个字段无用,从而使整个索引失效。

           因此,对于RBO优化器模式来说,想提高这个查询的速度,有效的索引是[curr_date, update_time],修改索引后再进行查询,速度明显提高。

           而CBO优化器模式相对灵活,它会根据SQL语句生成一组可能被使用的执行计划,估算出每个执行计划的代价,并调用计划生成器(Plan Generator)生成执行计划,比较执行计划的代价,最终选择选择一个代价最小的执行计划。使用原先的三个字段作为索引,也不会有问题。

  • 相关阅读:
    ossec配置使用腾讯企业邮箱告警
    网络排除工具之tcping
    pyenv 安装
    CVE-2020-1472 漏洞检测
    容器技术的核心
    简述 进程、线程、协程的区别 以及应用场景--记录
    php函数使用
    php使用表单post方法进行页面
    CURL方式使用代理访问网站
    nginx下隐藏admin和当前域名下得index.php
  • 原文地址:https://www.cnblogs.com/yukifun/p/13024684.html
Copyright © 2020-2023  润新知