• oracle数据库中索引失效的几种情况


    原文1:https://blog.csdn.net/u012255097/article/details/102792683
    原文2:https://www.cnblogs.com/lanseyitai1224/p/9217177.html

    创建Oracle 索引的目的是为了避免全表扫描数据,提高查询效率,但是如果sql语句写的不好致使索引失效,反而会影响数据查询效率。以下几种情况就会导致索引失效:

    0.没有 WHERE 子句

    众所周知,添加索引的字段必需要在where条件后适当使用才会生效,如果连查询条件都没有,那肯定不会用到索引的。

    1.隐式转换导致索引失效.这一点应当引起重视.也是开发中经常会犯的错误。

    dept_id 是一个varchar2型的字段,但在查询时把该字段作为number类型以where条件传给Oracle,这样会导致索引失效。

    select * from temp where dept_id = 33333333333 ; //错误的例子
    
    select * from temp where dept_id ='33333333333'; //正确的例子
    

    原因:oracle 会自动把 where 子句转换成 to_number(dept_id)=33333333333,相当于使用函数,这样就限制了索引的使用。

    2.使用 IS NULL 和 IS NOT NULL

    select * from  emp  where colnum   is  null;  //使用 IS NULL后,colnum列的索引会失效
    

    3.WHERE 子句中使用函数不规范

    3.1转变一下:

    如果没有使用基于函数的索引,那么 where 子句中对存在索引的列使用函数时,会使优化器忽略掉这些索引。例如:

    select * from staff where trunc(birthdate) = '01-MAY-82';
    

    把函数应用在条件上,索引是可以生效的,把上面的语句改成下面的语句,就可以通过索引进行查找。

    select * from staff where birthdate < (to_date('01-MAY-82') + 0.9999);
    

    注意:对于 MIN, MAX 函数,Oracle 仍然使用索引。

    3.2基于函数的索引:

    使用Oracle内部函数导致索引失效.对于这样情况应当创建基于函数的索引.

      错误的例子:select * from test where round(id)=10; 说明,此时id的索引已经不起作用了
    
      正确的例子:首先建立函数索引,create index test_id_fbi_idx on test(round(id));然后 select * from test where  round(id)=10; 这时函数索引起作用了
    

    4.使用 LIKE ‘%T’ 进行模糊查询

    select * from student where name like 'aaa%';    //'aaa%' 会用到索引
    
    select * from student where name like '%aaa';    //'%aaa' 或者 '_aaa' 不会使用索引
    

    5.对索引列进行运算导致索引失效,我所指的对索引列进行运算包括(+,-,*,/,! 等)

    select * from test where id-1=9;  //错误的例子
    select * from test where id=10;  //正确的例子
    

    6.WHERE 子句中使用不等于操作

    不等于操作包括:<>, !=, NOT colum >= ?, NOT colum <= ?

    对于这个限制条件可以通过 OR 替代,例如: colum <> 0 ===> colum> 0 OR colum<0

    7.等于和范围索引不会被合并使用

    SELECT emp_id, emp_m, salary_q ... FROM emp WHERE job='manager' AND deptno>10
    

    job 和 deptno 都是非唯一索引,这种条件下 oracle 不会合并索引,它只会使用第一个索引。

    8. 不要在 SQL 代码中使用双引号。

    因为字符常量使用单引号。如果没有必要限定对象名称,可以使用(非 ANSI SQL 标准)括号将名称括起来。

    9. 将索引所在表空间和数据所在表空间分别设于不同的磁盘chunk上,有助于提高索引查询的效率。

    10. Oracle默认使用的基于代价的SQL优化器(CBO)非常依赖于统计信息,一旦统计信息不正常,会导致数 据库查询时不使用索引或使用错误的索引。

    一般来说,Oracle的自动任务里面会包含更新统计信息的语句,但如果表数据发生了比较大的变化(超过 20%),可以考虑立即手动更新统计信息,

    例如:analyze table abc compute statistics,但注意,更新统计 信息比较耗费系统资源,建议在系统空闲时执行。

    11. Oracle在进行一次查询时,一般对一个表只会使用一个索引。

    因此,有时候过多的索引可能导致Oracle使用错误的索引,降低查询效率。例如某表有索引1(Policyno) 和索引2( classcode),

    如果查询条件为 policyno=‘xx’ and classcode=‘xx’,则系统有可能会使用索引2,相较于使用索引1,查询效率明显降低。

    12. 优先且尽可能使用分区索引。

  • 相关阅读:
    async&await的前世今生
    如何使用cocos2dx-jsbinding 来处理分辨率适配
    cocos2d-x jsbinding 资源下载实现
    cocos2d-x jsbinding 在线更新策略设计
    xml2js
    快速入门cocos2d-x jsbinding
    cocos2d-x 工程目录结构说明
    Javascript 开发IDE
    认识cocos2d-x jsbinding
    MySQL 灵异事件一则 -- desc报语法错误
  • 原文地址:https://www.cnblogs.com/HelloXTF/p/12108514.html
Copyright © 2020-2023  润新知