热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

详解MySQL执行计划

这篇文章主要介绍了MySQL执行计划的相关资料,帮助大家更好的理解和使用MySQL,感兴趣的朋友可以了解下

EXPLAIN语句提供有关MySQL如何执行语句的信息。EXPLAIN与SELECT,DELETE,INSERT,REPLACE和UPDATE语句一起使用。

EXPLAIN为SELECT语句中使用的每个表返回一行信息。它按照MySQL在处理语句时读取它们的顺序列出了输出中的表。 MySQL使用嵌套循环连接方法解析所有连接。这意味着MySQL从第一个表中读取一行,然后在第二个表,第三个表中找到匹配的行,依此类推。处理完所有表后,MySQL输出所选列,并通过表列表回溯,直到找到一个表,其中有更多匹配的行。从这个表中读取下一行,然后继续处理下一个表。

1.  EXPLAIN 输出列

说下几个关键的列:

  • type :连接类型
  • possible_keys :可选的索引
  • key :实际执行时使用的索引
  • ref :ref列显示将哪些列或常量与前面key列中显示的命名的索引进行比较以从表中选择行
  • rows :rows列表示MySQL认为执行查询必须检查的行数

2.  连接类型

连接类型,顺序从最好到最差,依次是: 

system

表只有一行。这是const join类型的特例。

const

表最多有一个匹配行,在查询开始时读取。因为只有一行,所以这一行中的列的值可以被优化器的其余部分视为常量。const表非常快,因为它们只被读取一次。

当你用PRIMARY KEY或UNIQUE索引的所有部分与常量值进行比较时,将使用const。

例如,下面的表tbl_name可以被当做const表:

SELECT * FROM tbl_name WHERE primary_key=1;
SELECT * FROM tbl_name WHERE primary_key_part1=1 AND primary_key_part2=2;

eq_ref

对于前表中的每一行组合,从这个表中读取一行。除了system和const类型,这是可能的最好的联接类型。当一个索引的所有部分都被联接使用并且索引是PRIMARY KEY或UNIQUE NOT NULL索引时,使用它。

eq_ref可以用于使用=操作符进行比较的索引列。比较值可以是一个常量,也可以是使用在此表之前读取的表中的列的表达式。

例如,下面的例子中MySQL可以使用eq_ref连接来处理ref_table:

SELECT * FROM ref_table,other_table
 WHERE ref_table.key_column=other_table.column;

SELECT * FROM ref_table,other_table
 WHERE ref_table.key_column_part1=other_table.column AND ref_table.key_column_part2=1;

ref

对于前表中的行的每种组合,将从该表中读取具有匹配索引值的所有行。如果联接仅使用key的最左前缀,或者如果key不是PRIMARY KEY或UNIQUE索引(换句话说,如果联接无法基于key值选择单个行),则使用ref。如果使用的key仅匹配几行,则这是一种很好的联接类型。

ref可用于使用=或<=>运算符进行比较的索引列。

例如,下面的例子中,MySQL可以用ref连接来处理ref_table:

SELECT * FROM ref_table WHERE key_column=expr;

SELECT * FROM ref_table,other_table
 WHERE ref_table.key_column=other_table.column;

SELECT * FROM ref_table,other_table
 WHERE ref_table.key_column_part1=other_table.column
 AND ref_table.key_column_part2=1;

fulltext

使用FULLTEXT索引执行连接

ref_or_null

这种连接类型类似于ref,但是MySQL会额外搜索包含NULL值的行。此联接类型优化最常用于解析子查询。

例如,下面的例子中,MYSQL可以使用ref_or_null来处理ref_table:

SELECT * FROM ref_table WHERE key_column=expr OR key_column IS NULL;

index_merge

这种连接类型表明使用了索引合并优化。在这种情况下,输出行中的key列包含使用的索引列表,而key_len包含所使用索引的最长key部分列表。

unique_subquery

此类型将eq_ref替换为以下形式的某些IN子查询:

value IN (SELECT primary_key FROM single_table WHERE some_expr)

index_subquery

与unique_subquery类似,它代替了IN子查询,但适用于以下形式的子查询中的非唯一索引:

value IN (SELECT key_column FROM single_table WHERE some_expr)

range

只检索给定范围内的行,并使用索引来选择行。输出行中的key列指示使用了哪个索引。key_len包含所使用的最长的key部分。对于这种类型,ref列为NULL。

使用=,<>,>,> =,<,<=,IS NULL,<=>,BETWEEN,LIKE或IN()运算符将key列与常量进行比较时,可以使用range:

SELECT * FROM tbl_name WHERE key_column = 10;

SELECT * FROM tbl_name WHERE key_column BETWEEN 10 and 20;

SELECT * FROM tbl_name WHERE key_column IN (10,20,30);

SELECT * FROM tbl_name WHERE key_part1 = 10 AND key_part2 IN (10,20,30);

index

index连接类型与all是一样的,区别在于index连接类型扫描的时候索引树。通常,只发生在以下两种情况:

  • 如果索引是查询的覆盖索引,并且可用于满足表中所需的所有数据,则仅扫描索引树。在这种情况下,“Extra”列显示“Using index”。仅索引扫描通常比ALL快,因为索引的大小通常小于表数据。
  • 使用从索引读取数据以按索引顺序查找数据行来执行全表扫描。“Uses index”不会出现在Extra列中。

ALL

对前表的行的每个组合进行全表扫描。如果该表是未标记为const的第一个表,则通常不好,并且在所有其他情况下通常非常糟糕。通常,可以通过添加索引来避免ALL,这些索引允许基于早期表中的常量值或列值从表中检索行。 

3.  Extra列

关于Extra列的输出,只说几个常见的:

Using filesort

MySQL必须做一次额外操作,以找出如何按排序顺序检索行。排序是通过根据联接类型遍历所有行并存储与WHERE子句匹配的所有行的排序key和指向该行的指针来完成的。然后对key进行排序,并按排序顺序检索行。

Using index

仅使用索引树中的信息从表中检索列信息,而不需要执行额外的查找来读取实际行。当查询只使用属于单个索引的列时,可以使用此策略。

Using temporary

为了解析查询,MySQL需要创建一个临时表来保存结果。通常,如果查询包含以不同方式展示列的GROUP BY和ORDER BY子句,则会发生这种情况。

Using where 

WHERE子句用于限制哪些行匹配下一个表或发送给客户端。除非你打算从表中获取或检查所有行,否则如果额外的值没有使用where,并且表连接类型是all或index,则查询中可能出现错误。 

4.  优化ORDER BY

在某些情况下,MySQL可能会使用一个索引来满足ORDER BY子句,从而避免执行filesort操作所涉及的额外排序。

假设在(key_part1, key_part2)上有一个索引,下面的查询可以使用索引来解析ORDER BY部分。优化器是否真的这样做,取决于如果还必须读取索引之外的时,读取索引是否比表扫描更有效。

SELECT * FROM t1 ORDER BY key_part1, key_part2;

上面的语句,查询使用SELECT *,这可能会选择比key_part1和key_part2更多的列。在这种情况下,扫描整个索引并查找表行以查找索引中未包含的列可能比扫描表并排序结果要昂贵。如果是这样,则优化器不太可能使用索引。如果SELECT *仅选择索引列,则使用索引并避免排序。

下面这个查询中,key_part1是常量,因此通过索引访问的所有行都按key_part2顺序排列,并且如果WHERE子句的选择性足以使索引范围扫描比表扫描便宜,则在(key_part1,key_part2)上的索引可以避免排序:

SELECT * FROM t1 WHERE key_part1 = constant ORDER BY key_part2; 

以上就是详解 MySQL 执行计划的详细内容,更多关于MySQL 执行计划的资料请关注其它相关文章!


推荐阅读
  • 本文介绍了Paxos的世界中关于复制日志与状态机的概念和重要性。通过存储日志来实现数据的持久化,并通过日志流来记录数据的变化,而不是直接持久化数据本身。这样做的好处是简化了持久化存储的操作,并且方便多机之间的数据同步。 ... [详细]
  • 安装mysqlclient失败解决办法
    本文介绍了在MAC系统中,使用django使用mysql数据库报错的解决办法。通过源码安装mysqlclient或将mysql_config添加到系统环境变量中,可以解决安装mysqlclient失败的问题。同时,还介绍了查看mysql安装路径和使配置文件生效的方法。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 本文介绍了在Hibernate配置lazy=false时无法加载数据的问题,通过采用OpenSessionInView模式和修改数据库服务器版本解决了该问题。详细描述了问题的出现和解决过程,包括运行环境和数据库的配置信息。 ... [详细]
  • Oracle Database 10g许可授予信息及高级功能详解
    本文介绍了Oracle Database 10g许可授予信息及其中的高级功能,包括数据库优化数据包、SQL访问指导、SQL优化指导、SQL优化集和重组对象。同时提供了详细说明,指导用户在Oracle Database 10g中如何使用这些功能。 ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • 本文由编程笔记小编整理,介绍了PHP中的MySQL函数库及其常用函数,包括mysql_connect、mysql_error、mysql_select_db、mysql_query、mysql_affected_row、mysql_close等。希望对读者有一定的参考价值。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 数据库(外键及其约束理解)(https:www.cnblogs.comchenxiaoheip6909318.html)My ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
author-avatar
球球小白痴_693
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有