什么情况下Mysql索引会失效(%号篇)

纸上得来终觉浅,觉知此事要躬行.

你看懂了,和你自己实际操作过是不一样的,切记一定要自己是尝试动手。

首先 我的环境是 Mysql5.7(引擎是 InnoDB),Navicat12,这个不一定需要和我一样。
什么情况下Mysql索引会失效(%号篇)_第1张图片

第一,什么是索引?
索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。

索引是一种数据结构。数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。索引的实现通常使用B树及其变种B+树。

更通俗的说,索引就相当于目录。为了方便查找书中的内容,通过对内容建立索引形成目录。索引是一个文件,它是要占据物理空间的。

第二、索引有哪些优缺点?

索引的优点

(1)可以大大加快数据的检索速度,这也是创建索引的最主要的原因。

(2)通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。

索引的缺点

(1)时间方面:创建索引和维护索引要耗费时间,具体地,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,会降低增/改/删的执行效率;

(2)空间方面:索引需要占物理空间。

第三、测试索引

这里我先只建立了一个索引:
右键设计表能看到
什么情况下Mysql索引会失效(%号篇)_第2张图片
接下来,我们首先测试的是like 中 %号一定会使索引失效吗?

我们使用EXPLAIN 语句测试索引,语句如下:

EXPLAIN select * from pms_category where pms_category.`name` like '机%'

什么情况下Mysql索引会失效(%号篇)_第3张图片
图中一些字段的含义:
type=ALL:全表扫描,遍历整张表去查询匹配的结果,不走索引。
type=index:使用索引覆盖,仅仅扫描索引树,比ALL要快。
type=range:使用索引进行范围查询时就会用到range访问方法。
key:实际使用到的索引,如果为NULL就是没使用索引。

什么情况下Mysql索引会失效(%号篇)_第4张图片
很明显,百分号写在前,会导致索引失效

接下来我们再看一个,需要查询的只有加上索引的字段:
什么情况下Mysql索引会失效(%号篇)_第5张图片
嘿嘿索引又开始起作用了,这是为什么呢?我知道你很急,但你先别急。

让我们在做一个试验,这个的查询结果中只包含主键和新建的索引
什么情况下Mysql索引会失效(%号篇)_第6张图片
嘿嘿,索引依旧生效,继续看,我们查询的结果列中包含了非主键并且不是索引的字段,哦吼,失效了。

什么情况下Mysql索引会失效(%号篇)_第7张图片

首先说什么是索引覆盖?:
如果要查询的字段都建立过索引,那么引擎会直接在索引表中查询而不会访问原始数据(否则只要有一个字段没有建立索引就会做全表扫描),这叫索引覆盖。因此我们需要尽可能的在select后只写必要的查询字段,以增加索引覆盖的几率。

接下来,我来解释一下,为什么会有这种情况。
因为,LIKE查询以%开头使用了索引的原因就是使用了索引覆盖。
针对二级索引MySQL提供了一个优化技术。即从辅助索引中就可以得到查询的记录,就不需要回表再根据聚集索引查询一次完整记录。使用索引覆盖的一个好处是辅助索引不包含整行记录的所有信息,故其大小要远小于聚集索引,因此可以减少大量的IO操作,但是前提是要查询的所有列必须都加了索引。

LIKE查询以%开头会导致全索引扫描或者全表扫描,如果没有索引覆盖的话,查询到的数据会回表,多了一次IO操作,当MySQL预估全表扫描或全索引扫描的时间比走索引花费的时间更少时,就不会走索引。有了索引覆盖就不需要回表了,减少了IO操作,花费的时间更少,所以就使用了索引。

总结:就是说如果查询的结果中只包含主键和索引字段则会使用索引,反之则不会。
那有人就会说了,为什么我在设计表的时候,不把所有的字段全设置为索引呢,**这里值得注意的是不要想着为每个字段建立索引,因为优先使用索引的优势就在于其体积小 **

文中如有问题,请大家指出,都是不对发现问题解决问题,这样大家都能提升,谢谢大家。

你可能感兴趣的:(mysql,数据库,java)