上一章我们讲述了索引调优实战在Join的过程,那么本章重点阐述索引失效的场景及原因剖析!

1、索引失效场景

老规矩先导入一些表作为数据使用,表的所有定义在这个链接中:

Mysql高级调优篇表补充——建表SQL_风清扬逍遥子的博客-CSDN博客⭐️tbl_emp⭐️CREATE TABLE `tbl_emp` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(20) DEFAULT NULL,`deptId` int(11) DEFAULT NULL,PRIMARY KEY (`id`) ,KEY `fk_dept_id`(`deptId`))ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8;⭐️tbl_dhttps://blog.csdn.net/qq_31821733/article/details/120886389?spm=1001.2014.3001.5501        导入staffs员工表:

1.1、全值匹配我最爱

我们添加了索引:

看第一个Sql:select * from staffs where name='July';

我建立了复合索引分别是name,age,pos,我只查一个,索引会不会失效?

看下执行计划可以知道走索引上,你建立三个,我走了1个,没问题

再来一个Sql:select * from staffs where name='July' and age = 25;

执行计划知道,走部分索引一样没问题。

但是不知道有没有发现一个问题!!Extra为Null??这个是第一次出现,那么这里我要重点强调下,Extra为Null的时候,如果走了索引,说明这个查询,进行了回表!!

那么什么是回表呢?简单来说,如果你查询的字段,存在非索引字段,那么查询的时候,Mysql虽然根据了你的条件得到了这个记录,但是不在索引的字段无法通过索引的方式直接得到,只能通过拿到该条记录的主键索引,再从数据行里读,我们知道Mysql索引文件和数据文件是在两个不同的文件里的,要去读磁盘;所以索引文件建立的效果,就是帮助我们对数据进行排序和查找效率的优化,不至于去读数据行进行额外的IO开销;

所以这里字段我用select *,因为复合索引里没有add_time这个字段,所以无法直接查出来add_time这个列的记录,要通过定位到主键,然后再读一次数据行才可以得到这个记录,称为回表。

如果我这么写,就不会出现回表,因为pos在索引列中!

         而查add_time,就回表了:

那我再加一个字段pos,很明显精度越高,key_len的长度就越长。总结是【全值匹配我最爱】

现在三种2情况都正常,我们来看一些特殊场景!

explain select * from staffs where age = 23 and pos = 'dev'; 执行计划走一下发现

索引怎么不走了?再看看这个sql:select * from staffs where pos = 'dev';

索引也不走!

再来一个sql:select * from staffs where name = 'zhangsan';走索引了

总结下来:如果查询中没有开头的索引,也就是不告诉我1楼在哪里,让我从2楼或者3口开始找索引,不好意思,我找不到,只能全表扫!违背了【最佳左前缀法则】

回顾下我们建立的索引,(name, age, pos)顺序是1楼,2楼,3楼;如果索引了多列,要遵守最左前缀法则,指的是查询从索引的最左前列开始并且不跳过索引中的列。即【带头大哥不能死】

再看下这个sql:select * from staffs where name = 'zhangsan' and pos = 'dev'; 这个sql等于中间2楼断开了,执行计划显示这个key_len和只有name的时候一样,说明只走了name索引,Extra中出现Using index condition,这个是5.6后新加的特性,会先条件过滤索引,过滤完索引后找到所有符合索引条件的数据行,随后用 WHERE 子句中的其他条件去过滤这些数据行;其实没有什么用,就是走到了索引上的意思。【中间兄弟不能断】

 总结:全值匹配我最爱,最左前缀要遵守;带头大哥不能死,中间兄弟不能断;

1.2、勿在索引列做任何操作

不要在索引列上做任何操作,包括计算,函数,自动或者手动类型转换,会导致索引失效而转向全表扫描。

举例子:explain select * from staffs where left(name, 4) = 'July'; 查找name左往右4个字符为July的行。索引失效了!

总结:【索引列上少计算】

1.3、范围之后全失效

这个上一节提过,like后面的索引会失效,即Mysql存储引擎不能使用索引中,范围条件右边的列!

举例子,explain select * from staffs where name = 'July' and age > 14 and pos = 'manager'; 因为2楼已经是范围查找了,age用到了索引,进行范围查找,但是后面的索引pos就失效了,因为你告诉我2楼,没告诉我去3楼的路,所以我找不到3楼的目录,定位不到3楼,只能挨个去找入口!这里要注意,5.7以前的优化,是如果出现了范围查找,则当前范围的索引也不走,而5.7后,范围索引之后的才失效,所以这里的key_len=78,单个name话是74,三个都走是140。

1.4、尽量使用覆盖索引

查询语句中只访问索引的查询,索引列和查询列尽量保持一致,或者查询列<=索引列:

看这个sql:explain select * from staffs where name = 'July' and age = 15 and pos = 'manager'; 如果用了* ,我说过会回表!但是指定了索引的列,那么就走了覆盖索引,Using index是很好的效果!

包括以下的场景也是一样!

1.5、不等于场景下索引失效

Mysql在使用不等于的场景下,无法使用索引导致全表扫描

explain select * from staffs where name != 'July'; 执行计划后发现

以及explain select * from staffs where name <> 'July';

1.6、is null、is not null无法使用索引

看下这个sql:explain select * from staffs where name is null; 这个就很离谱了

explain select * from staffs where name is not null;

1.7、Like百分写最右

like以通配符开头('%abc...')时,Mysql索引会失效变成全表扫!

比如这个sql:explain select * from staffs where name like '%July%';

如果是这样的,也是一样:explain select * from staffs where name like '%July'; 原因我这里不多解释了,上几章节都有。

但是这样的话,就不会失效:explain select * from staffs where name like 'July%';

因为like是范围查找,百分号在后面,Mysql会拿到字典序进行排序的方式查找对应的情况,而百分号在前面,Mysql就不知道从哪个字母开始找,于是便全表扫描。

那这个是不是解决不了?实际面试中经常会这么问:如何解决like '%xxx%' 字符时索引不被使用的情况?

答案是用覆盖索引避免索引失效,我们这里的索引是(name, age, pos),索引我们在查询的时候不要写select *,只要写具体的字段值,任何一个列被覆盖索引覆盖,就可以解决两边百分号的问题!!! 

如果我这么写的话,肯定不行,因为add_time不在覆盖索引内

总结:【like百分写最右】+【覆盖索引解决双百分问题】

1.8、字符串不加单引号索引失效

比如这个sql:explain select * from staffs where name = 222; 索引失效

而这个是成功走到索引的:explain select * from staffs where name = '222';

Mysql很聪明,你以为你给我的我就查不到了,你给我的Int型的时候,实际这个字段是varchar型,传入数字会隐式的帮你转换成varchar类型,前面说过不要让Mysql做这些自动或者手动的类型转换,否则索引失效!当然查询的结果,是不会有变化的,只是sql执行上有转换。

1.9、少用or

少用or,会导致索引失效,不是不用;

比如explain select * from staffs where name = 'July' or name = 'z3'; 虽然都是带头大哥的name,但是索引一样丢失了。

2、总结口诀

  • 全值匹配我最爱,最左前缀要遵守;
  • 带头大哥不能死,中间兄弟不能断;
  • 索引列上少计算,范围之后全失效;
  • Like百分写最右,覆盖索引不写星;
  • 不等空值还有or,索引失效要少用;
  • VAR引号不可丢,SQL高级并不难!

这些口诀,可以帮助我们的记忆!

本章讲的这一切,才是真真正正能写出高性能的JavaEE系统的实战核心关键知识点,以后写sql或多或少都会在脑子里记忆,都会自我分析,为上线前减少了很多不必要的开销,也是晋级高级或者架构师的必备之路,共勉!下一章节,索引面试总结和调优其他开发细节知识点!

Mysql高级调优篇——第四章:Sql实战调优场景剖析(下)相关推荐

  1. oracle延时盲注如何防止,【原创】WEB安全第四章SQL注入篇21 oracle 延时注入

    WEB安全第四章SQL注入篇21 oracle 延时注入 1.简介 DBMS_LOCK.SLEEP()函数可以让一个过程休眠很多秒,但使用该函数存在许多限制.首先,不能直接将该函数注入子查询中,因为O ...

  2. C语言入门——《明解C语言》入门篇第四章练习

    新开C语言专栏整理一下学C的艰苦之路,先从看书+视频开始. 整理了<明解C语言>入门篇第四章练习的"参考答案",记录一下学习的过程.直接上代码. 练习4-1 int m ...

  3. 数据库系统原理——第四章 SQL与数据库的基本操作(1)知识点总结(自考本)

    当你想挣一百块的时候你就要把目标定成一千块,这样才挣得更多. 第四章 SQL与数据库的基本操作 SQL概述 什么是SQL? SQL的特点 SQL的四大功能 数据定义语言 数据操纵语言 数据控制语言 嵌 ...

  4. photoshop第十四章:制作阳光浪漫场景效果

    第十四章:制作阳光浪漫场景效果 1.制作良辰美景效果 素材: 1 2 3 4 5 效果: (1)打开照片"背景" (2)选中工具栏中的"矩形选框工具"-> ...

  5. 第四章 SQL聚合函数 COUNT(二)

    文章目录 第四章 SQL聚合函数 COUNT(二) 权限 性能 未提交事务所做的更改 示例 第四章 SQL聚合函数 COUNT(二) 权限 要使用COUNT(*),必须对指定的表具有表级别的SELEC ...

  6. 第二十四章 SQL函数 CEILING

    文章目录 第二十四章 SQL函数 CEILING 大纲 参数 描述 示例 第二十四章 SQL函数 CEILING 数值函数,返回大于或等于给定数值表达式的最小整数. 大纲 CEILING(numeri ...

  7. 第九十四章 SQL函数 %MINUS

    文章目录 第九十四章 SQL函数 %MINUS 大纲 参数 描述 示例 第九十四章 SQL函数 %MINUS 将数字转换为规范整理格式,然后反转符号的整理函数. 大纲 %MINUS(expressio ...

  8. 第十四章 SQL命令 CREATE TABLE(一)

    文章目录 第十四章 SQL命令 CREATE TABLE(一) 大纲 参数 描述 语法概述 SQL安全和权限 表名 表存在 第十四章 SQL命令 CREATE TABLE(一) 创建表 大纲 CREA ...

  9. 第六十四章 SQL函数 INSTR

    文章目录 第六十四章 SQL函数 INSTR 大纲 参数 描述 INSTR, CHARINDEX, POSITION和$FIND 示例 第六十四章 SQL函数 INSTR 返回子字符串在字符串中的位置 ...

最新文章

  1. 一分钟详解PCL中点云配准技术
  2. php 画虚线,HTML5 Canvas绘制圆点虚线实例_html5教程技巧
  3. idea从安装到项目启动
  4. jboss as安装配置_书评:JBoss AS 7:配置,部署和管理
  5. mounted钩子函数_Vue 探索之路——生命周期和钩子函数的一些理解
  6. react文字滚动插件_【赠书】Preact(React)核心原理详解
  7. android网页去广告插件下载,Adblock Plus(去广告插件)APP增强稳定版
  8. 嵌入Circle映射和逐维小孔成像反向学习的鲸鱼优化算法
  9. 基于StackGAN++、CycleGAN的图像生成工具,开源
  10. chrome插件实现简单网页实时翻译
  11. Lambda表达式练习【应用】
  12. javascript实现汉诺塔
  13. cassandra权威指南
  14. 2022 极术通讯—AR的元宇宙
  15. 计算机网络安全论文选题提纲,计算机网络安全毕业论文提纲
  16. 从比特保存和信息保存看数字资源长期保存
  17. CANoe 从入门到精通
  18. ameya:什么是连接器 连接器采购平台有哪些
  19. #pragma DATA_SECTION与#pragma CODE_SECTION的使用
  20. Redis高可用方案对比

热门文章

  1. 深度强化学习的前景:帮助机器掌控复杂性
  2. 张一鸣卸任CEO,立下10年之约,期望突破线性延伸
  3. CSDN湘苗培优|高起点步入职场,快人一步!
  4. 帮AI体检看病一条龙服务,阿里发布“AI安全诊断大师”
  5. Python PK C++,究竟谁更胜一筹?
  6. 自带数据线的迷你数显充电宝,旅途必备
  7. 2097352GB地图数据,AI技术酷炫渲染,《微软飞行模拟器》游戏即将上线
  8. 近万个Python开源项目中精选Top34!
  9. 监控告警满飞天,运维在家睡到自然醒...
  10. Http持久连接与HttpClient连接池