oracle数据库索引失效的问题及解决

 更新时间:2025年01月09日 10:07:23   作者:喜羊羊love红太狼  
本文总结了在Oracle数据库中索引失效的一些常见场景,包括使用isnull、isnotnull、!=、<、>、函数处理、like前置%查询以及范围索引和等值索引同时存在等情况,通过实际的SQL查询验证,展示了索引失效的原因,并给出了相应的优化建议

oracle数据库索引失效问题

场景

在开发中有时候遇到某个表中的列明明是创建了索引,但查询时却发现索引失效。

环境

下面是工作流activiti中的两张表act_hi_procinst、act_hi_taskinst关系是一对多(一个流程包含多个流程环节),一个是历史流程表,一个是历史流程环节表。

索引失效情况及验证

(单表act_hi_procinst已经在delete_reason_列上创建了索引 )

验证一:索引列为is null 和 is not null时,索引失效

select * from act_hi_procinst t where t.delete_reason_ is not null;
select * from act_hi_procinst t where t.delete_reason_ is null;

全表扫描,该列索引失效

select * from act_hi_procinst t where t.delete_reason_ ='ACTIVITI_DELETED' and rownum < 1000;

索引生效,Oracle 数据库使用索引范围扫描方式。

这种扫描方式通过索引键值的范围来定位需要的数据。

select * from act_hi_procinst t where t.delete_reason_ is not null
and t.start_time_ between TO_DATE('2023-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
and TO_DATE('2023-12-31 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
and rownum < 1000

结论一

经验证索引列查询使用is null 和 is not null则该列索引失效。

验证二:索引列为 !=和 <> 时会导致该索引列失效

select * from act_hi_procinst t where t.delete_reason_ !='ACTIVITI_DELETED';
select * from act_hi_procinst t where t.delete_reason_ <>'ACTIVITI_DELETED';

结论二

经验证索引列查询使用 !=和 <> 时会导致该索引列失效

验证三:索引列用函数处理则该索引会失效

select * from act_hi_procinst t where to_char(start_time_,'YYYY')= '2023'

结论三

索引列用函数处理则该索引会失效,如字符串函数trunc,to_char,substring,to_date等函数

区别下面的sql(下面的sql走索引)

select * from act_hi_procinst t where t.start_time_ >= TO_DATE('2023-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS');

验证四:索引列使用like的前置%查询,则该索引列失效。

select * from act_hi_procinst t where t.business_key_ like '%20230103-0000102'

like 使用后置百分号走索引

结论四

经验证索引列使用like的前置%查询时会导致该索引列失效,但是使用了ike的后置%则会走索引

验证五:范围索引查询和等值索引查询同时存在,则范围索引失效

其中start_time_创建有普通索引,delete_reason_字段也创建了普通索引

  • SQL一:
select * from act_hi_procinst t where t.start_time_
between TO_DATE('2023-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
and TO_DATE('2023-12-31 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
and t.delete_reason_ ='ACTIVITI_DELETED'
and rownum < 1000;
  • SQL二:
select * from act_hi_procinst t
where t.start_time_ >= TO_DATE('2023-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
and t.start_time_<= TO_DATE('2023-12-31 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
and t.delete_reason_ ='ACTIVITI_DELETED'
and rownum < 1000

结论五

范围索引查询和等值索引查询同时存在,则范围索引失效

注:上面的查询sql中加 rownum < 1000的目的主要是数据量太大,这里只是要验证一下查询是否走索引列

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Oracle date如何比较大小分析

    Oracle date如何比较大小分析

    本文将详细介绍Oracle date如何比较大小,需要了解更多的朋友可以参考下
    2012-11-11
  • Oracle行级触发器的使用操作

    Oracle行级触发器的使用操作

    这篇文章主要介绍了Oracle行级触发器的使用,创建触发器并使用dblink在插入时进行数据同步,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-05-05
  • Oracle 监控索引使用率脚本分享

    Oracle 监控索引使用率脚本分享

    这篇文章主要介绍了Oracle 监控索引使用率脚本分享,本文给出的脚本将得到索引的使用率,可以很好的度量索引的使用情况以及根据这个值来判断当前的这些索引是否可以被移除或改进,需要的朋友可以参考下
    2014-09-09
  • Oracle中行列转换的实现方法汇总

    Oracle中行列转换的实现方法汇总

    行列转换是指将行数据转换为列数据,或将列数据转换为行数据的过程,本文主要介绍了Oracle中行列转换的实现方法汇总,用PIVOT和UNPIVOT函数来实现,具有一定的参考价值,感兴趣的可以了解一下
    2024-02-02
  • oracle 树查询 语句

    oracle 树查询 语句

    oracle 树查询,需要的朋友可以参考下,代码有点乱不好意思啊
    2009-07-07
  • oracle覆盖导入dmp文件的2种方法

    oracle覆盖导入dmp文件的2种方法

    oracle如何覆盖导入dmp文件呢?很多朋友对这一问题不是很清楚,今天小编通过分享oracle覆盖导入dmp文件的2种方法,感兴趣的朋友跟随小编一起看看吧
    2021-05-05
  • Oracle数据库中的触发器详解

    Oracle数据库中的触发器详解

    这篇文章主要给大家介绍了关于Oracle数据库中触发器的相关资料,触发器也是保护数据完整性的一种重要方法,于存储过程不同的是,触发器是通过事件进行触发被执行,存储过程需要被调用执行,需要的朋友可以参考下
    2024-02-02
  • Oracle客户端版本及位数(Windows系统)查看方法

    Oracle客户端版本及位数(Windows系统)查看方法

    这篇文章主要介绍了Windows系统下Oracle客户端版本及位数查看方法,感兴趣的小伙伴们可以参考一下
    2016-08-08
  • Oracle中查询重复记录的几种方法实现

    Oracle中查询重复记录的几种方法实现

    这篇文章主要介绍了Oracle中查询重复记录的方法实现,包含使用GROUP BY和HAVING语句,使用窗口函数ROW_NUMBER()和使用自连接查询这三种方式,具有一定的参考价值,感兴趣的可以了解一下
    2024-06-06
  • windows使用sqlpus连接oracle 数据库的教程图解

    windows使用sqlpus连接oracle 数据库的教程图解

    这篇文章主要介绍了windows使用sqlpus连接oracle 数据库的教程图解,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-08-08

最新评论