zoukankan      html  css  js  c++  java
  • 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)生成执行计划,比较执行计划的代价,最终选择选择一个代价最小的执行计划。使用原先的三个字段作为索引,也不会有问题。

  • 相关阅读:
    HADOOP docker(六):hive简易使用指南
    HADOOP docker(四):安装hive
    HADOOP docker(二):HDFS 高可用原理
    Python 自用代码(调整日期格式)
    Python 自用代码(某方标准类网页源代码清洗)
    python合并多个csv文件并去重
    Python连接MySQL乱码(中文变问号)
    Shell实现循环执行curl向Solr导入json文件
    Python 自用代码(拆分txt文件)
    shell报错:未预期的符号***附近有语法错误
  • 原文地址:https://www.cnblogs.com/yukifun/p/13024684.html
Copyright © 2011-2022 走看看