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. 范围查询之后范围查询之后的索引字段,会失效?。。〉旧碛美捶段Р檠哪歉鏊饕侄我廊挥行В缤贾械膕tatus 。
- 而图中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)都在索引列上时,才能真正使用索引 。
关于覆盖索引,可以参考这篇 -> 索引原理,设计原则
文章插图
8. MySQL认为全表更快
文章插图
此处是由于数据的特殊性,‘北京市’所占的比例很高,还不如全表扫描
文章插图
8.1 is null 和 is not null
本质上跟上边是一样的
推荐阅读
- 【MySQL】Navicat15 安装
- 31 《吐血整理》高级系列教程-吃透Fiddler抓包教程-Fiddler如何抓取Android系统中Flutter应用程序的包
- 「MySQL高级篇」MySQL索引原理,设计原则
- 我的世界怎么用附魔台附魔书(我的世界用高级附魔台怎么附魔)
- MySQL 索引失效-模糊查询,最左匹配原则,OR条件等。
- 30 《吐血整理》高级系列教程-吃透Fiddler抓包教程-Fiddler如何抓取Android7.0以上的Https包-番外篇
- MySQL 全局锁、表级锁、行级锁,你搞清楚了吗?
- llinux下mysql建库、新建用户、用户授权、修改用户密码
- RedHat7.6安装mysql8步骤
- 29 《吐血整理》高级系列教程-吃透Fiddler抓包教程-Fiddler如何抓取Android7.0以上的Https包-终篇