您当前的位置:首页 > 电脑百科 > 数据库 > MYSQL

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了吗?

时间:2019-09-07 11:27:53  来源:  作者:
MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了吗?

 

在我们使用MySQL的过程中,随着数据量越来越大,查询显得有些吃力,这时候就要针对查询就行优化,针对查询优化,通过给字段添加索引可以提高数据的读取速度,提高项目的并发能力和抗压能力。在上一篇我们讲了给数据库中的表添加索引,来提高它的查询速度,但是会有另外一种情况出现,那就是我们给表中字段加了索引,但是查询的时候依旧很慢,没有什么变化,这时就是因为建立的索引失效了,今天就来讲一讲索引失效的情况!

对于查看索引是否失效,MySQL数据库针对每一条SQL语句,提供了一个查看它的执行计划的工具,叫做EXPLAIN,咱们先来了解一下这个工具。首先说一下接下来用到的表,创建的表结构为:

CREATE TABLE `tb_user` (
 `id` BIGINT (20),
 `user_name` VARCHAR (200),
 `user_password` VARCHAR (200),
 `birth` DATETIME ,
 `sex` CHAR (4),
				 `age` int(8),
 `email` VARCHAR (200),
 `mobile` VARCHAR (200),
 `create_date` DATETIME ,
 `update_date` DATETIME ,
 `description` VARCHAR (800)
) ENGINE=INNODB;

创建一个存储函数,向里面插入一百万条数据:

DELIMITER $$
CREATE
 PROCEDURE insert_tb_user()
 BEGIN
 DECLARE i INT;
 SET i=0;
 WHILE i>=0 && i<= 1000000 DO
 INSERT INTO tb_user
 (`id`, `user_name`, `user_password`, `birth`, `sex`, `age`, `email`, `mobile`, `create_date`, `update_date`, `description`) VALUES
 (i,concat('admin',i),concat('admin',i),NOW(),'M',i,'admin@qq.com',concat('12345',i),NOW(),NOW(),concat('超级管理员',i));
 SET i=i + 1;
 END WHILE;
 
 END$$
DELIMITER ;
-- 执行存储函数
call insert_tb_user()

生成的表数据如下:

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了吗?

 

利用这个表,我们来介绍一下执行计划和索引失效的情况。

首先来看一下执行计划的结果是什么样的,执行计划的查看,就是在查询语句的前面加上EXPLAIN关键字就可以了:

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了吗?

 

对于这些字段的意思,咱们一一来解释:

一、 id,SELECT识别符。

*id相同时,执行顺序由上至下

*如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行

二、select_type,查询中每个select子句的类型

*SIMPLE(简单SELECT,不使用UNION或子查询等)

*PRIMARY(子查询中最外层查询)

*UNION(UNION中的第二个或后面的SELECT语句)

*DEPENDENT UNION(UNION中的第二个或后面的SELECT语句)

*UNION RESULT(UNION的结果,union语句中第二个select开始后面所有select)

*SUBQUERY(子查询中的第一个SELECT,结果不依赖于外部查询)

*DEPENDENT SUBQUERY(子查询中的第一个SELECT,依赖于外部查询)

* DERIVED(派生表的SELECT, FROM子句的子查询)

* UNCACHEABLE SUBQUERY(一个子查询的结果不能被缓存,必须重新评估外链接的第一行)

三、 table,显示这一步所访问数据库中表名称。

四、type,对表访问方式

*all:Full Table Scan, MySQL将遍历全表以找到匹配的行

*index: Full Index Scan,index与ALL区别为index类型只遍历索引树

*range:只检索给定范围的行,使用一个索引来选择行

*ref: 表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值

*eq_ref: 类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用primary key或者 unique key作为关联条件

*const、system: 当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where列表中,MySQL就能将该查询转换为一个常量,system是const类型的特例,当查询的表只有一行的情况下,使用system

*NULL: MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。

五、 possible_keys,可能使用的索引。

六、key,实际使用的索引

七、key_len,索引中使用的字节数,可通过该列计算查询中使用的索引的长度

八、ref,列与索引的比较,表示上述表的连接匹配条件

九、rows,估算出结果集行数

十、Extra,MySQL解决查询的详细信息

*Using where:不用读取表中所有信息,仅通过索引就可以获取所需数据

*Using temporary:表示MySQL需要使用临时表来存储结果集,group by ; order by

*Using filesort:包含 order by ,而且无法利用索引完成的排序操作称为“文件排序”

*Using join buffer:该值强调了在获取连接条件时没有使用索引,并且需要连接缓冲区来存储中间结果。

*Impossible where:这个值强调了where语句会导致没有符合条件的行。

*Select tables optimized away:这个值意味着仅通过使用索引,优化器可能仅从聚合函数结果中返回一行

*No tables used:Query语句中使用from dual 或不含任何from子句

以上就是对EXPLAIN工具的一个介绍,了解了这个工具后,我们结合这个执行工具,来看一看哪些情况会导致这个索引失效!

第一种情况:针对联合索引,是否遵循最左匹配原则;

我们user_name,user_password,mobile建立一个联合索引,如下:

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了吗?

 

联合索引其实是建立了三个索引,也就是user_name的索引,user_name,user_password的索引,user_name,user_password,mobile的索引,最左匹配原则的意思,是否在语句中使用了最左建立的索引,也就是user_name的索引,演示一下:

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了吗?

 

当我们把user_name的查询条件去掉之后,会是什么情况呢?

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了吗?

 

我们会看到索引已经失效了,用的是全表扫描,违背了最左匹配的原则,那么对于查询语句select * from tb_user where user_password='admin66666' and user_name='admin66666' and mobile='1234566666'会用到索引吗?答案如下:

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了吗?

 

也是用到了联合索引,这和你条件中写的顺序是没有关系的!

第二种情况:在索引列上做了函数操作,会导致索引失效而导致全表扫描

我们先把那个联合索引删除掉,然后在user_name这一列上建立一个唯一索引:

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了吗?

 


MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了吗?

 


MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了吗?

 

先不在索引列上做函数操作,执行计划如下:

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了吗?

 

很显然使用了索引,那么索引列进行函数操作呢?例如做一个字符拼接的操作:

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了吗?

 

第三种情况:语句中like查询是以%开头,索引会失效变成全表扫描,覆盖索引。

示例如下:

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了吗?

 

如果模糊查询不是以%开头的,那么也是可以用到索引的:

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了吗?

 

第四种情况:使用is not null 会导致无法使用索引

示例如下:

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了吗?

 

第五种情况:查询语句中,如果条件中有or,即使其中有条件带索引也不会使用。要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了吗?

 

上面的sql语句是可以用到索引的,当我们把and换成or时,就会变成全表扫描:

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了吗?

 

这时我们对mobile也加上索引,这条sql语句也就会使用上索引:

MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了吗?

 


MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了吗?

 

第六种情况:使用不等于(!= 或者<>)的时候,无法使用索引,会导致索引失效

第七种情况:不能使用索引中范围条件右边的列,范围之后索引失效。(< ,> between and)

这些情况就不在进行实际操作了,感兴趣的朋友可以动手操作一下,也许随着MySQL版本的更新迭代,对这些查询语句进行内部优化,一些索引失效的情况就会消失。除了以上这些情况会导致索引失效,还有哪些情况会导致索引失效呢?



Tags:MySQL索引   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
Mysql索引数据结构下面列举了常见的数据结构 二叉树 红黑树 Hash表 B-Tree(B树)Select * from t where t.col=5我们在执行一条查询的Sql语句时候,在数据量比较大又不加索引的情...【详细内容】
2021-06-07  Tags: MySQL索引  点击:(90)  评论:(0)  加入收藏
聊聊Mysql索引和redis跳表 ---redis的有序集合zset数据结构底层采用了跳表原理 时间复杂度O(logn)(阿里)redis使用跳表不用B+数的原因是:redis是内存数据库,而B+树纯粹是为了m...【详细内容】
2021-02-05  Tags: MySQL索引  点击:(190)  评论:(0)  加入收藏
本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题。特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引...【详细内容】
2020-08-16  Tags: MySQL索引  点击:(55)  评论:(0)  加入收藏
为了能让索引能有更直观的效率,我在一张表里扔进了百万条数据(光靠这些数据,生成数据代码写了一个小时,解决MySQL8的文件导入权限问题解决了两个小时,导入数据花费了一个小时,我...【详细内容】
2020-08-05  Tags: MySQL索引  点击:(66)  评论:(0)  加入收藏
概述随着电商的发展,使用数据库的业务越来越复杂,除了掌握哪些场景可以使用索引,哪些场景适合使用索引,还需要掌握索引在运行过程中的一些使用规则,特别是组合索引的使用。比如索...【详细内容】
2020-07-06  Tags: MySQL索引  点击:(54)  评论:(0)  加入收藏
1 初识索引索引在MySQL中也叫是一种“键”,是存储引擎用于快速找到记录的一种数据结构。索引对于良好的性能非常关键,尤其是当表中的数据量越来越大时,索引对于性能的影响愈发...【详细内容】
2019-11-18  Tags: MySQL索引  点击:(95)  评论:(0)  加入收藏
概述在关系数据库中,索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构,它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页...【详细内容】
2019-09-12  Tags: MySQL索引  点击:(130)  评论:(0)  加入收藏
在我们使用MySQL的过程中,随着数据量越来越大,查询显得有些吃力,这时候就要针对查询就行优化,针对查询优化,通过给字段添加索引可以提高数据的读取速度,提高项目的并发能力和抗压...【详细内容】
2019-09-07  Tags: MySQL索引  点击:(100)  评论:(0)  加入收藏
索引是一种用于快速查询行的数据结构,就像一本书的目录就是一个索引,如果想在一本书中找到某个主题,一般会先找到对应页码。在mysql中,存储引擎用类似的方法使用索引,先在索引中...【详细内容】
2019-09-05  Tags: MySQL索引  点击:(278)  评论:(0)  加入收藏
索引目的索引的目的在于提高查询效率,可以类比字典,如果要查“mysql”这个单词,我们肯定需要定位到m字母,然后从下往下找到y字母,再找到剩下的sql。如果没有索引,那么你可能需要把...【详细内容】
2019-08-29  Tags: MySQL索引  点击:(187)  评论:(0)  加入收藏
▌简易百科推荐
作者:雷文霆 爱可生华东交付服务部 DBA 成员,主要负责Mysql故障处理及相关技术支持。爱好看书,电影。座右铭,每一个不曾起舞的日子,都是对生命的辜负。 本文来源:原创投稿 *爱可生...【详细内容】
2021-12-24  爱可生    Tags:MySQL   点击:(7)  评论:(0)  加入收藏
生成间隙(gap)锁、临键(next-key)锁的前提条件 是在 RR 隔离级别下。有关Mysql记录锁、间隙(gap)锁、临键锁(next-key)锁的一些理论知识之前有写过,详细内容可以看这篇文章...【详细内容】
2021-12-14  python数据分析    Tags:MySQL记录锁   点击:(18)  评论:(0)  加入收藏
binlog 基本认识 MySQL的二进制日志可以说是MySQL最重要的日志了,它记录了所有的DDL和DML(除了数据查询语句)语句,以事件形式记录,还包含语句所执行的消耗的时间,MySQL的二...【详细内容】
2021-12-14  linux上的码农    Tags:mysql   点击:(13)  评论:(0)  加入收藏
为查询优化你的查询 大多数的MySQL服务器都开启了查询缓存。这是提高性最有效的方法之一,而且这是被MySQL的数据库引擎处理的。当有很多相同的查询被执行了多次的时候,这些查...【详细内容】
2021-12-09  元宇宙iwemeta    Tags:mysql   点击:(15)  评论:(0)  加入收藏
测试的目的和原因,公司有很多程序员,每个程序员对数据库和表结构都有自己的理解。而且每个程序员的理解往往是以效率考虑。既然都是为了效率考虑,那么我就来测试一下究竟哪种使...【详细内容】
2021-12-08  吴彬的分享    Tags:Mysql数据库   点击:(14)  评论:(0)  加入收藏
当你们考虑项目并发的时候,我在部署环境,当你们在纠结使用ArrayList还是LinkedArrayList的时候,我还是在部署环境。所以啊,技术不止境,我在部环境。今天这篇文章缕一下在同一台服...【详细内容】
2021-12-08  秃头码哥    Tags:MySQL数据库   点击:(17)  评论:(0)  加入收藏
对于数据分析来说,MySQL使用最多的是查询,比如对数据进行排序、分组、去重、汇总及字符串匹配等,如果查询的数据涉及多个表,还需要要对表进行连接,本文就来说说MySQL中常用的查询...【详细内容】
2021-12-06  笨鸟学数据分析    Tags:MySQL   点击:(21)  评论:(0)  加入收藏
在学习SQL语句之前,首先需要区分几个概念,我们常说的数据库是指数据库软件,例如MySQL、Oracle、SQL Server等,而本文提到的数据库是指数据库软件中的一个个用于存储数据的容器。...【详细内容】
2021-11-24  笨鸟学数据分析    Tags:SQL语句   点击:(23)  评论:(0)  加入收藏
概述以前参加过一个库存系统,由于其业务复杂性,搞了很多个应用来支撑。这样的话一份库存数据就有可能同时有多个应用来修改库存数据。比如说,有定时任务域xx.cron,和SystemA域...【详细内容】
2021-11-05  Java云海    Tags:分布式锁   点击:(31)  评论:(0)  加入收藏
MySQL的进阶查询 一、 按关键字排序 使用ORDERBY语句来实现排序排序可针对一个或多个字段ASC:升序,默认排序方式 【升序是从小到大】DESC:降序 【降序是从大到小】ORDER BY的...【详细内容】
2021-11-05  Java热点    Tags:SQL语句   点击:(28)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条