索引失效的情况 -----可能
索引主要看where 、group by 、order by
1.组合索引不遵循最佳左前缀法制。最佳左前缀法制:如果索引了多列,要遵循最左前缀法则,指的是查询从索引的最左前列开始并且不跳过索引中的列。如组合索引为A B C 只有ABC,AB,AC,A会名中组合索引,命中数量不一样分别是3,2,1,1命中数量越多查询性能越好
2.不在索引列上做任何计算、函数操作,会导致索引失效而转向全表扫描。
3.存储引擎不能使用索引中范围条件右边的列。如组合索引为A B C ,where A=0 and B>100 and C=7 只会命中 AB
4.MySQL在使用不等于时无法使用索引会导致全表扫描。!=
5.is null 可以使用索引,但是is not null无法使用索引。
6.like以通配符开头会使索引失效导致全表扫描。
7.字符串不加单引号索引会失效。
8.使用or连接时索引失效
在我学习如上时,以为这个是铁规矩,直到今天才发现上面这几个索引失效的情况只是可能会失效。先说结论,经过本人测试以上几种情况只有在select *的时候才会出现;如果是正常的给字段不用 * 一般都会被MySQL优化器优化走索引
创建组合索引
1.符合最左前缀
–不走组合索引
EXPLAIN
SELECT * FROM category
where type=1
2.不符合最左前缀
–走组合索引
EXPLAIN
SELECT status,type,name FROM category
where type=1
3.不符合最左前缀 不符合or失效
–走组合索引
EXPLAIN
SELECT status,type,name FROM category
where type=1 OR status=1
4.不符合最左前缀 不符合or失效
–走组合索引
EXPLAIN
SELECT status,type,name FROM category
where type=1 OR status=1
GROUP BY name ,status,type
相信你们也能自己动手发现如果用status,type,name ,符合了索引失效情况但还是走了索引,这是因为上面呢?
我们来看看MySQL的内部执行流程
图是网上找的
内部有一个优化器,优化器根据表的大小、索引情况、统计数据等信息,选择最佳的执行计划,以最小的代价返回结果集。这个过程有时候也被称为“查询重写”。
下面就可下结论了:select * 下面的条件不会被优化,而select 字段1,字段2 会被优化器优化。怪不得阿里规范叫我们不要使用select *
那么select 字段1,字段2 索引到底什么走索引,什么时候不走索引啊?
这个还真说不准,可能被优化器优化了就走索引了
那么有人可能会说那么那8条有什么用啊?直接select 字段1,字段2 优化交给优化器 就不用背了。
这里我认为它更像一种规范,符合规范做事会让系统内部少走弯路,也能提高性能
优化建议
and会自动调整顺序为最左前列
对于单值索引,尽量选择针对当前查询字段过滤性更好的索引
于组合索引,当前where查询中过滤性更好的字段在索引字段顺序中位置越靠前越好
对于组合索引,尽量选择能够包含在当前查询中where子句中更多字段的索引
尽可能通过分析统计信息和调整query的写法来达到选择合适索引的目的