1. 不满足最左前缀所谓最左前缀,可以想象成一个爬楼梯的过程,假设我们有一个复合索引:name,status,address,那这个楼梯由低到高依次顺序是:name,status,address,最左前缀,要求我们不能出现跳跃楼梯的情况,否则会导致我们的索引失效:?
- 按楼梯从低到高,无出现跳跃的情况--此时符合最左前缀原则,索引不会失效

文章插图
- 出现跳跃的情况
- 直接第一层name都不走,当然都失效

文章插图
- 走了第一层,但是后续直接第三层,只有出现跳跃情况前的不会失效(此处就只有name成功)

文章插图
- 同时,这个顺序并不是由我们where中的排列顺序决定,比如:
- where name='小米科技' and status='1' and address='北京市'
- where status='1' and name='小米科技' and address='北京市'
其实是因为我们MySQL有一个Optimizer(查询优化器),查询优化器会将SQL进行优化,选择最优的查询计划来执行 。2. 范围查询之后范围查询之后的索引字段,会失效!!!但本身用来范围查询的那个索引字段依然有效,如图中的status 。
- 而图中address失效了,对比一下长度便可看出来 。

文章插图
3. 索引字段做运算对索引字段做运算,使用函数等都会导致索引失效 。

文章插图
4. 字符串不加' '索引字段为字符串类型,由于在查询时,没有对字符串加单引号,MySQL的查询优化器,会自动的进行类型转换,造成索引失效 。
5. 避免select *危害
- 消耗更多的 CPU 和 IO 以网络带宽资源
- 可减少表结构变更带来的影响
- 无法使用覆盖索引
当查询列中包含了非索引项,虽然我们还是能够利用到索引,但是为了获取非索引项字段,我们需要回表去查询数据,效率会比较低 。?
6. or分割开的条件用or分割开的条件, 如果or前的条件中的列有索引,而后面的列中没有索引,那么涉及的索引都不会被用到 。?
示例,name字段是索引列 , 而createtime不是索引列,中间是or进行连接是不走索引的 :
- 因为有一个不走索引,又是or条件,两个都要判断一下,相当于不管如何,都还是得去走全表查询,没有利用到索引 。
explain select * from tb_seller where name='黑马程序员' or createtime = '2088-01-01 12:00:00'\G;

文章插图
7. 以%开头的Like模糊查询可以联系字典树Trie的匹配吧 。
- 比如要找‘abc’,如果是%bc,一开始的根都找不到了,自然没办法利用到索引树
- 而如果是ab%,还能利用到前两个 。
- %开头的失效,%结尾的还能利用索引(实际上这里就相当于字符串的最左前缀原则,可以这么理解)

文章插图
解决方法:使用覆盖索引当真的需要两边都使用%来模糊查询时,只有当 作为模糊查询的条件字段(例子中的name)以及 想要查询出来的数据字段(例子中的 name & status & address)都在索引列上时,才能真正使用索引 。
经验总结扩展阅读
- 31 《吐血整理》高级系列教程-吃透Fiddler抓包教程-Fiddler如何抓取Android系统中Flutter应用程序的包
- 「MySQL高级篇」MySQL索引原理,设计原则
- 我的世界怎么用附魔台附魔书(我的世界用高级附魔台怎么附魔)
- MySQL 索引失效-模糊查询,最左匹配原则,OR条件等。
- 30 《吐血整理》高级系列教程-吃透Fiddler抓包教程-Fiddler如何抓取Android7.0以上的Https包-番外篇
- MySQL 全局锁、表级锁、行级锁,你搞清楚了吗?
- 轻奢极简店名美甲 名字高级小众美甲店名
- llinux下mysql建库、新建用户、用户授权、修改用户密码
- RedHat7.6安装mysql8步骤
- 我不完美但我独一无二签名 很高级酷酷的签名