一、explain是什么?

简单来讲就是官方给的一个优化工具,直接在你的SQL语句前加上explain,执行整条语句,之后你就可以根据执行结果优化你的SQL啦,废话不多说,直接刚实例

测试实例

1、创建测试表

  1. CREATE TABLE `sql_explain_student` (

  2. `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增ID',

  3. `name` varchar(30) DEFAULT NULL COMMENT '学生名字',

  4. `age` int(11) DEFAULT NULL COMMENT '学生年龄',

  5. `sex` tinyint(4) DEFAULT NULL COMMENT '性别',

  6. `class` int(11) DEFAULT NULL COMMENT '学生班级',

  7. PRIMARY KEY (`id`)

  8. ) ENGINE=InnoDB DEFAULT CHARSET=utf8

数据自己随意建

2、来个简单的测试语句

  1. select * from sql_explain_student;

  2. explain

  3. select * from sql_explain_student;

结果:

之后我们就可以根据结果分析我们的语句的优劣,及如何优化了(先看看看这个表里的变量都是什么意思,,好吧~)

二、explain字段解释及SQL好坏的判断

table:显示这一行的数据是关于哪张表的

type:这是重要的列,显示连接使用了何种类型。从最好到最差的连接类型为const、eq_reg、ref、range、index和ALL

type显示的是访问类型,是较为重要的一个指标,结果值从好到坏依次是: system>const>eq_ref>ref>fulltext>ref_or_null>index_merge>unique_subquery>index_subquery>range>index>ALL 一般来说,得保证查询至少达到range级别,最好能达到ref。

possible_keys:显示可能应用在这张表中的索引。如果为空,没有可能的索引。可以为相关的域从WHERE语句中选择一个合适的语句

key: 实际使用的索引。如果为NULL,则没有使用索引。很少的情况下,MYSQL会选择优化不足的索引。这种情况下,可以在SELECT语句中使用USE INDEX(indexname)来强制使用一个索引或者用IGNORE INDEX(indexname)来强制MYSQL忽略索引

key_len:使用的索引的长度。在不损失精确性的情况下,长度越短越好

ref:显示索引的哪一列被使用了,如果可能的话,是一个常数

rows:MYSQL认为必须检查的用来返回请求数据的行数

Extra:关于MYSQL如何解析查询的额外信息。坏的例子是Using temporary和Using filesort,意思MYSQL根本不能使用索引,结果是检索会很慢

extra列返回的描述的意义

Distinct:一旦MYSQL找到了与行相联合匹配的行,就不再搜索了

Not exists: MYSQL优化了LEFT JOIN,一旦它找到了匹配LEFT JOIN标准的行,就不再搜索了

Range checked for each Record(index map:#):没有找到理想的索引,因此对于从前面表中来的每一个行组合,MYSQL检查使用哪个索引,并用它来从表中返回行。这是使用索引的最慢的连接之一

Using filesort: 看到这个的时候,查询就需要优化了。MYSQL需要进行额外的步骤来发现如何对返回的行排序。它根据连接类型以及存储排序键值和匹配条件的全部行的行指针来排序全部行

Using index: 列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表的全部的请求列都是同一个索引的部分的时候

Using temporary 看到这个的时候,查询需要优化了。这里,MYSQL需要创建一个临时表来存储结果,这通常发生在对不同的列集进行ORDER BY上,而不是GROUP BY上

Where used 使用了WHERE从句来限制哪些行将与下一张表匹配或者是返回给用户。如果不想返回表中的全部行,并且连接类型ALL或index,这就会发生,或者是查询有问题不同连接类型的解释(按照效率高低的顺序排序)

system 表只有一行:system表。这是const连接类型的特殊情况

const:表中的一个记录的最大值能够匹配这个查询(索引可以是主键或惟一索引)。因为只有一行,这个值实际就是常数,因为MYSQL先读这个值然后把它当做常数来对待

eq_ref:在连接中,MYSQL在查询时,从前面的表中,对每一个记录的联合都从表中读取一个记录,它在查询使用了索引为主键或惟一键的全部时使用

ref:这个连接类型只有在查询使用了不是惟一或主键的键或者是这些类型的部分(比如,利用最左边前缀)时发生。对于之前的表的每一个行联合,全部记录都将从表中读出。这个类型严重依赖于根据索引匹配的记录多少—越少越好

range:这个连接类型使用索引返回一个范围中的行,比如使用>或<查找东西时发生的情况

index: 这个连接类型对前面的表中的每一个记录联合进行完全扫描(比ALL更好,因为索引一般小于表数据)

ALL:这个连接类型对于前面的每一个记录联合进行完全扫描,这一般比较糟糕,应该尽量避免

三、附录:explain字段详细解释

id SELECT识别符。这是SELECT的查询序列号
select_type SELECT类型,可以为以下任何一种:
SIMPLE:简单SELECT(不使用UNION或子查询)
PRIMARY:最外面的SELECT
UNION:UNION中的第二个或后面的SELECT语句
DEPENDENT UNION:UNION中的第二个或后面的SELECT语句,取决于外面的查询
UNION RESULT:UNION 的结果SUBQUERY:子查询中的第一个SELECT
DEPENDENT SUBQUERY:子查询中的第一个SELECT,取决于外面的查询
DERIVED:导出表的SELECT(FROM子句的子查询)
table 输出的行所引用的表
type 联接类型。下面给出各种联接类型,按照从最佳类型到最坏类型进行排序:
system:表仅有一行(=系统表)。这是const联接类型的一个特例。
const:表最多有一个匹配行,它将在查询开始时被读取。因为仅有一行,在这行的列值可被优化器剩余部分认为是常数。const表很快,因为它们只读取一次!
eqref:对于每个来自于前面的表的行组合,从该表中读取一行。这可能是最好的联接类型,除了const类型。
ref:对于每个来自于前面的表的行组合,所有有匹配索引值的行将从这张表中读取。
refornull:该联接类型如同ref,但是添加了MySQL可以专门搜索包含NULL值的行。indexmerge:该联接类型表示使用了索引合并优化方法。
uniquesubquery:该类型替换了下面形式的IN子查询的ref: value IN (SELECT primarykey FROM singletable WHERE someexpr) uniquesubquery是一个索引查找函数,可以完全替换子查询,效率更高。
indexsubquery:该联接类型类似于uniquesubquery。可以替换IN子查询,但只适合下列形式的子查询中的非唯一索引: value IN (SELECT keycolumn FROM singletable WHERE someexpr)
range:只检索给定范围的行,使用一个索引来选择行。
index:该联接类型与ALL相同,除了只有索引树被扫描。这通常比ALL快,因为索引文件通常比数据文件小。
ALL:对于每个来自于先前的表的行组合,进行完整的表扫描。
possible_keys 指出MySQL能使用哪个索引在该表中找到行
key 显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL。
key_len 显示MySQL决定使用的键长度。如果键是NULL,则长度为NULL。
ref 显示使用哪个列或常数与key一起从表中选择行。
rows 显示MySQL认为它执行查询时必须检查的行数。多行之间的数据相乘可以估算要处理的行数。
filtered 显示了通过条件过滤出的行数的百分比估计值。
Extra 该列包含MySQL解决查询的详细信息
Distinct:MySQL发现第1个匹配行后,停止为当前的行组合搜索更多的行。
Not exists:MySQL能够对查询进行LEFT JOIN优化,发现1个匹配LEFT JOIN标准的行后,不再为前面的的行组合在该表内检查更多的行。
range checked for each record (index map: #):MySQL没有发现好的可以使用的索引,但发现如果来自前面的表的列值已知,可能部分索引可以使用。
Using filesort:MySQL需要额外的一次传递,以找出如何按排序顺序检索行。
Using index:从只使用索引树中的信息而不需要进一步搜索读取实际的行来检索表中的列信息。
Using temporary:为了解决查询,MySQL需要创建一个临时表来容纳结果。
Using where:WHERE 子句用于限制哪一个行匹配下一个表或发送到客户。
Using sortunion(...), Using union(...), Using intersect(...):这些函数说明如何为indexmerge联接类型合并索引扫描。
Using index for group-by:类似于访问表的Using index方式,Using index for group-by表示MySQL发现了一个索引,可以用来查 询GROUP BY或DISTINCT查询的所有列,而不要额外搜索硬盘访问实际的表。

MySQL性能优化神器—explain的更多相关文章

  1. MySQL性能优化神器Explain

    本文涉及:MySQL性能优化神器Explain的使用 简介 虽然使用Explain不能够马上调优我们的SQL,它也不能给予我们一些调整建议,但是它能够让我们了解MySQL 优化器是如何执行SQL 语句 ...

  2. MySQL 性能优化神器 Explain 使用分析

    简介 MySQL 提供了一个 EXPLAIN 命令, 它可以对 SELECT 语句进行分析, 并输出 SELECT 执行的详细信息, 以供开发人员针对性优化. EXPLAIN 命令用法十分简单, 在 ...

  3. python mysql索引 优化神器explain 慢查询

    ##############总结########## 数据库中专门帮助用户快速找到数据的一种数据结构 类似于字典的目录的索引 索引的作用:约束和加速查找 工作原理: b+树形结构 最上层是树根,中间是 ...

  4. MySql 性能优化之 Explain

    MySQL 之 Explain 输出分析 背景 前面的文章写过 MySQL 的事务和锁,这篇文章我们来聊聊 MySQL 的 Explain,估计大家在工作或者面试中多多少少都会接触过这个.可能工作中实 ...

  5. Mysql系列-性能优化神器EXPLAIN使用介绍及分析

    MySQL 提供了一个 EXPLAIN 命令, 它可以对 SELECT 语句进行分析, 并输出 SELECT 执行的详细信息, 以供开发人员针对性优化. EXPLAIN 命令用法十分简单, 在 SEL ...

  6. 神奇的 SQL 之 MySQL 性能分析神器 → EXPLAIN,SQL 起飞的基石!

    前言 开心一刻 某人养了一头猪,烦了想放生,可是猪认识回家的路,放生几次它都自己回来了.一日,这个人想了个狠办法,开车带着猪转了好多路进山区放生,放生后又各种打转,然后掏出电话给家里人打了个电话,问道 ...

  7. mysql性能优化-慢查询分析、优化索引和配置 (慢查询日志,explain,profile)

    mysql性能优化-慢查询分析.优化索引和配置 (慢查询日志,explain,profile) 一.优化概述 二.查询与索引优化分析 1性能瓶颈定位 Show命令 慢查询日志 explain分析查询 ...

  8. mysql性能优化随笔

    mysql性能优化是一个很大的命题,这里只记录一下近期的一些小经验. 曾经以为看了点create table时加index的语法就觉得自己知道怎么做mysql优化了,后来又看了点介绍mysql索引底层 ...

  9. Mysql - 性能优化之子查询

    记得在做项目的时候, 听到过一句话, 尽量不要使用子查询, 那么这一篇就来看一下, 这句话是否是正确的. 那在这之前, 需要介绍一些概念性东西和mysql对语句的大致处理. 当Mysql Server ...

随机推荐

  1. java~springboot~ibatis数组in查询的实现

    在ibatis的xml文件里,我们去写sql语句,对应mapper类的方法,这些sql语句与控制台上没什么两样,但在有些功能上需要注意,如where in这种从数组里查询符合条件的集合里,需要在xml ...

  2. LindDotNetCore~授权中间件的介绍

    回到目录 LindDotNetCore中间件 大叔认识中间件就是主要对http请求进行拦截,然后添加具体个性化功能的逻辑,这种把请求切开,添加新逻辑的方式一般称为面向方面的逻辑AOP! 授权中间件 请 ...

  3. Redis学习笔记~分布锁的使用

    回到目录 分布锁主要用在多进程共同访问同一个资源时候,用来保持同一时间段只能有一个进程执行,同时避免了并发冲突的出现,这在很多场景都会用到,像秒杀库存,抽奖库存,多操作者处理一家公司等. void T ...

  4. 学习ASP.NET Core Razor 编程系列十四——文件上传功能(二)

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  5. 学习ASP.NET Core Razor 编程系列十二——在页面中增加校验

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  6. Docker最全教程——数据库容器化之持久保存数据(十一)

    上一节我们讲述了SQL Server容器化实践(注意,SQL Server现在也支持跨平台),本节将讲述如何持久保存数据,并且接下来将逐步讲解其他数据库(MySql.Redis.Mongodb等等)的 ...

  7. 文件输入输出流工具: IOUtils使用总结

    序言 以前写文件的复制很麻烦,需要各种输入流,然后读取line,输出到输出流...其实apache.commons.io里面提供了输入流输出流的常用工具方法,非常方便.下面就结合源码,看看IOUTil ...

  8. C# 委托基础1.0

    在C# 1.0中提出了一种新特性叫作:委托.委托本质上一种类型.是对特定方法的抽象,定义委托后,可以将方法封装,把方法当参数,传递 using System; using System.Collect ...

  9. [转]Node.js 应用:Koa2 使用 JWT 进行鉴权

    本文转自:https://www.cnblogs.com/linxin/p/9491342.html 前言 在前后端分离的开发中,通过 Restful API 进行数据交互时,如果没有对 API 进行 ...

  10. 通过Hutool 调用远程API接口(POST/GET)

    背景:需要调用第三方接口,开启某项任务,用Hutool代替了HttpClient 调用第三方接口,简单粗暴. 代码如下: import java.util.Date; import org.apach ...