linuxsir首页 LinuxSir.Org | Linux、BSD、Solaris、Unix | 开源传万世,因有我参与欢迎您!
网站首页 | 设为首页 | 加入收藏
您所在的位置:主页 > Linux数据库 >

Oracle Index 索引无效原因及解决

时间:2019-03-03  来源:未知  作者:admin666

如上图,虽然索引已经被引用,但是速度依旧很慢,莫非是虽然启用了索引,但是又被其他的一些原因拖慢了速度,继续调查。
调查途中,收集到一些Oracle 数据库不走索引的原因分享给大家

不走索引的原因 1. 在索引列上使用函数时不会使用索引

例如常见的,TO_CHAR、TO_DATE、TO_NUMBER、TRUNC ...等等。
此时的解决办法可以使用函数索引,顾名思义就是把使用函数后的字段整体当成索引中的字段。
如下图中的TO_CHAR(SHOHOU_DATE, 'YYYYMMDD')就是一个函数索引,因为日期字段中含有时分秒,进行日期比较的时候,必须转化成固定的格式。

CREATE INDEX ID_TT_SHOHOU_HIST_003
ON TT_SHOHOU_HIST
(DEL_FLG,TO_CHAR(SHOHOU_DATE, 'YYYYMMDD'), SHOHOU_ID)
TABLESPACE SALESPA_INDEX
2. 索引的列进行隐式的类型转换
SELECT * FROM TABLE WHERE INDEX_COLUM = 5

上面语句中的INDEX_COLUM字段类型为VARCHAR2,这时就会发生隐式类型转换,类似于

SELECT * FROM TABLE WHERE TO_NUMBER(INDEX_COLUM) = 5
3. WHERE 子句中使用不等于操作

不等于操作包括: , !=, NOT colum = ?, NOT colum = ?
替代方式可以使用OR, colum 0 ===== colum 0 or colum

4. 使用 IS NULL 和 IS NOT NULL

替代方式:函数索引
通过nvl(b,c)将为空的字段转为不为空的c值,再在函数nvl(b,c)上建立函数索引
转换前

SELECT * FROM A WHERE B = NULL

转换后

SELECT * FROM A WHERE NVL(B,C) = C
5. 组合索引

组合索引:由多个列构成的索引。如

CREATE INDEX INDEX_EMP ON EMP (COL1,COL2,COL3,...)

INDEX_EMP则为复合索引,COL1为引导列。进行查询时,可以使用WHERE COL1 = ?,也可以使用WHERE COL1 = ? AND COL2 = ?,这样的限制条件都会使用索引,但是WHERE COL2 = ?,不会使用索引,所以限制条件中包含引导列时,该限制条件才会使用组合索引。

经过一番调查,我使用的SQL语句检索条件中对时间列进行TO_CHAR(TTSH.SHOHOU_DATE, 'YYYYMMDD')格式化日期,去除掉时分秒。再建立函数索引后仍然没有起到优化加速的效果,仔细观察发现在使用TO_CHAR格式化时间之后,又进行TO_DATE转为时间格式和其他子查询的字段进行比较。然后很快想到,建立一个TO_DATE(TO_CHAR(TTSH.SHOHOU_DATE, 'YYYYMMDD'), 'YYYYMMDD')这样的函数索引,结果缺失提高了不少的运行速度,从4~5s缩短到了0.5s左右。

友情链接