哪些情况下不需要使用索引
1、数据唯一性差的字段不要使用索引比如性别,只有两种可能数据。意味着索引的二叉树级别少,多是平级。这样的二叉树查找无异于全表扫描。2、频繁更新的字段不要使用索引比如logincount登录次数,频繁变化导致索引也频繁变化,增大数据库工作量,降低效率。3、字段不在where语句出现时不要添加索引只有在where语句出现,mysql才会去使用索引4、数据量少的表不要使用索引,使用了改善也不大
5、如果mysql估计使用全表扫描要比使用索引快,则不会使用索引。
索引不可用的情况
有一天我遇到了一个同事的求助,他让我帮忙优化一个SQL,这个SQL执行时间很长。于是我查询了执行计划,发现这个SQL竟然要进行一次全表扫描。当时我查看了表的定义,发现在where子句中的条件列上是建了索引的,那为什么执行计划会显示全表扫描呢。这个问题困扰了我很长时间,于是后来我又看了看表的定义,发现了问题的根本所在:作为条件的字段是varchar,而SQL语句中的条件是一串数字!
这样的话就会造成索引不可用,处理方法也很简单,加上一对单引号就可以了。
以下几种情况索引不会被使用
1、不等于操作不能用于索引
2、经过普通或者函数运算的索引列不能使用索引
3、含前向模糊查询(通配符%在搜索词首出现),比如“like %王xx”【反向键索引:reverse】
4、索引列为空,或包含空值
5、数值比较时左右类型不同,相当于做了隐式类型转换
6、给索引查询的值是未知字段,而不是已知数
注:
1、通配符放在后面不一定就能走索引,因为这时对索引是一个范围扫描,如果oracle通过统计数据认为这个范围比较大,那么走索引得到的代价评估值就更大,这时就不会选择走索引。
2、如果通配符放在前面,oracle几乎可以肯定是不会选择走索引的(除非oracle确定该sql只需要访问该索引而不需要访问表)。因为这时必须是索引全扫描,而全扫描索引本身就会消耗大量 资源,然后再根据得出的rowid(很有可能也很多)去扫描表又要消耗大量资源,这个查询总共消耗的资源很可能会比直接扫描全表慢很多。
3、如果你认为自己比oracle更了解自己的查询语句和数据分布情况,你确定更多情况走索引是正确的,那就使用hint强制要求走索引。