MySQL 的 EXPLAIN 命令可以查看SELECT语句的执行的计划,是 MySQL 查询优化的必备工具。

通过执行计划可以了解查询方式、索引使用情况、需要扫描的数据量以及是否需要临时表或排序操作等信息。

我们需要分析执行计划对查询进行有的放矢的优化。

需要注意:

  • EXPLAIN不考虑触发器、存储过程或用户自定义函数对查询的影响
  • EXPLAIN不考虑缓存
  • EXPLAIN只能分析执行计划,不能显示存储引擎在执行查询过程中进行的操作
  • 部分统计信息是估算的,并非精确值

本文基于 MySQL 5.6 版本。

EXPLAIN SELECT * FROM `user`
JOIN `post` ON `user`.id = `post`.uid
WHERE user.`created_at` < '2018-10-01 00:00:00' AND `post`.status = 1;

结果:

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE user range PRIMARY,idx_created_at idx_created_at 7 null 19440 Using index condition; Using where; Using temporary; Using filesort
1 SIMPLE post ref idx_uid,idx_status idx_uid 8 user.id 1 Using where

EXPLAIN 的行数为查询涉及的表数, 结果各列的含义为:

  • id: 查询的唯一标识
  • select_type: 查询的类型
  • table: 查询的表, 可能是数据库中的表/视图,也可能是 FROM 中的子查询
  • type: 搜索数据的方法
  • possible_keys: 可能使用的索引
  • key: 最终决定要使用的key
  • key_len: 查询索引使用的字节数。通常越少越好
  • ref: 查询的列或常量
  • rows: 需要扫描的行数,估计值。通常越少越好
  • extra: 额外的信息

select type

select_type 可能的值有:

  • SIMPLE: 简单查询,不包含子查询和union
  • PRIMRARY: 包含子查询时的最外层查询; 使用union时的第一个查询
  • UNION: 包含union的查询中非第一个查询
  • DEPENDENT UNION: 与 UNION 相同,但依赖外层查询的结果
  • SUBQUERY: 子查询
  • DEPENDENT SUBQUERY: 依赖外层查询的子查询
  • DERIVED: 用于 FROM 中的子查询

下面给出几个示例:

EXPLAIN SELECT * FROM post WHERE uid = (
SELECT id FROM user WHERE name = "finley"
);
id select_type table
1 PRIMARY post
2 SUBQUERY user

DEPENDENT SUBQUERY:

EXPLAIN SELECT * FROM post WHERE uid = (
SELECT id FROM user WHERE name = "finley" AND post.uid=user.id
);
id select_type table
1 PRIMARY post
2 DEPENDENT SUBQUERY user

type

type 字段描述了查询的方式,从好到坏为:

  1. null: 不需要访问索引和表即可完成, 示例: SELECT 1;

  2. const: 表中仅有一行匹配,在分解查询计划时直接将其读出作为常量使用。system 是 const 类型的特例。

    示例:SELECT id FROM user WHERE name = "hdt3213";

    id select_type table type possible_keys key key_len ref rows Extra
    1 SIMPLE user const uni_name uni_name 258 const 1 Using index

UNIQUE KEY uni_name (name) ON user

  1. eq_ref: 使用 PRIMARY KEY 或 UNIQUE KEY 进行关联查询。

    示例: SELECT * FROM post JOIN user ON post.uid = user.id WHERE user.gender = 'M';

    id select_type table type possible_keys key key_len ref rows Extra
    1 SIMPLE post ALL idx_uid 0 0 0 57796 null
    1 SIMPLE user eq_ref PRIMARY PRIMARY 8 post.uid 1 Using where
  2. ref: 使用允许重复的索引进行查询

    示例: SELECT * FROM user WHERE phone='12345678901';

    id select_type table type possible_keys key key_len ref rows Extra
    1 SIMPLE user ref idx_phone idx_phone 259 const 1 Using index condition
  3. range: 使用索引进行范围查询:

    示例: SELECT * FROM user WHERE age>18;

    id select_type table type possible_keys key key_len ref rows Extra
    1 SIMPLE user ref idx_age idx_age 259 const 1 null
  4. index: 在索引上进行顺序扫描。常见于在多列索引中未使用最左列进行查询。

    示例: SELECT * FROM user WHERE last_name='smith'

    id select_type table type possible_keys key key_len ref rows Extra
    1 SIMPLE user ref idx_full_name idx_full_name 259 const 1 Using where
  5. all: 扫描全表,最坏的情况

extra

extra 列显示了查询过程中需要执行的其它操作,有些情况应尽力避免。

  • using filesort: 查询时执行了排序操作而无法使用索引排序。虽然名称为'file'但操作可能是在内存中执行的,取决是否有足够的内存进行排序。

    应尽量避免这种filesort出现。
  • using temporary: 使用临时表存储中间结果,常见于ORDER BY和GROUP BY语句中。临时表可能在内存中也可能在硬盘中,应尽量避免这种操作出现。
  • using index: 索引中包含查询的所有列不需要查询数据表(回表)。可以加快查询速度。
  • using where: 使用了WHERE从句来限制哪些行将与下一张表匹配或者是返回给客户端
  • using index condition: 索引条件推送(MySQL 5.6 新特性),服务器层将不能直接使用索引的查询条件推送给存储引擎,从而避免在服务器层进行过滤。
  • distinct: 优化distinct操作,查询到匹配的数据后停止继续搜索

MySQL EXPLAIN 命令: 查看查询执行计划的更多相关文章

  1. Mysql中explain命令查看语句执行概况

    Mysql中可以使用explain命令查看查询语句的执行方式,使用方法举例:explain + 查询语句 例如:explain select * from user_info 几个重要的字段说明: t ...

  2. MySQL的EXPLAIN命令用于SQL语句的查询执行计划

    MySQL的EXPLAIN命令用于SQL语句的查询执行计划(QEP).这条命令的输出结果能够让我们了解MySQL 优化器是如何执行SQL 语句的.这条命令并没有提供任何调整建议,但它能够提供重要的信息 ...

  3. MySQL 优化之EXPLAIN详解(执行计划)

    学习MySQL时我们都知道索引对于一个SQL的优化很重要,而EXPLAIN关键字在分析是否正确以及高效的增加了索引时起到关键性的作用. 这篇文章显示了如何调用“EXPLAIN”来获取关于查询执行计划的 ...

  4. EXPLAIN 查看 SQL 执行计划

    EXPLAIN 查看 SQL 执行计划.分析索引的效率: id:id 列数字越大越先执行: 如果说数字一样大,那么就从上往下依次执行,id列为null的就表是这是一个结果集,不需要使用它来进行查询. ...

  5. 转载:MySQL EXPLAIN 命令详解学习

    转载自:https://blog.csdn.net/mchdba/article/details/9190771 MySQL EXPLAIN 命令详解 MySQL的EXPLAIN命令用于SQL语句的查 ...

  6. MySQL EXPLAIN 命令详解

    MySQL EXPLAIN 命令详解 MySQL的EXPLAIN命令用于SQL语句的查询执行计划(QEP).这条命令的输出结果能够让我们了解MySQL 优化器是如何执行SQL 语句的.这条命令并没有提 ...

  7. 第九课——MySQL优化之索引和执行计划

    一.创建索引需要关注什么? 1.关注基数列唯一键的数量: 比如性别,该列只有男女之分,所以性别列基数是2: 2.关注选择性列唯一键与行数的比值,这个比值范围在0~1之前,值越小越好: 其实,选择性列唯 ...

  8. mysql之优化器、执行计划、简单优化

    mysql之优化器.执行计划.简单优化 2018-12-12 15:11 烟雨楼人 阅读(794) 评论(0) 编辑 收藏 引用连接: https://blog.csdn.net/DrDanger/a ...

  9. 查看Oracle执行计划的几种方法

    查看Oracle执行计划的几种方法 一.通过PL/SQL Dev工具 1.直接File->New->Explain Plan Window,在窗口中执行sql可以查看计划结果.其中,Cos ...

随机推荐

  1. OpenAL音频库例程

    Windows下C++可用的OpenAL demo. 基于alut工具库的OpenAL例程,涵盖了基本的OpenAL指令,对部分作出了注释,并且可以播放(当然得把对应的音频文件放到正确的路径下). # ...

  2. 排序算法(sorting algorithm)之 插入排序(insertion sort)

    https://en.wikipedia.org/wiki/Insertion_sort loop1: 4,6,1,3,7 -> 4,6,1,3,7 loop2: 4,6,1,3,7 -> ...

  3. 怎样用git上传代码到github以及如何更新代码

    上传代码: 1.进入指定文件夹: cd 指定文件夹 2.初始化git仓库: git init 3.将项目所有文件添加到暂存区: git add . 4.提交到仓库: git commit -m &qu ...

  4. 可遇不可求的Question之SQLSERVER触发器不支持多行插入操作篇

    描述: 我们经常遇到 insert table_a select * from table_b 这样的语句, 同时在表table_a中根据每一条新增的SQL语句,通过触发器来触发对应的一系列的后续操作 ...

  5. MAC OS 更新GIT版本时遇到的问题

    在更新git版本时,没有备份就删掉了原先的版本,在安装完2.18.0的新版本后,使用命令行git --version,返回错误git not a developer tool or in PATH. ...

  6. 四面美团,收割 offer

    阅读本文大概需要 6 分钟. 来源:https://blog.csdn.net/csuliyajin2012/article/details/49430659 美团我是在拉勾网上投的简历,之前也投过一 ...

  7. vi命令详解(转)

    vi编辑器是所有Unix及Linux系统下标准的编辑器,它的强大不逊色于任何最新的文本编辑器,这里只是简单地介绍一下它的用法和一小部分指令.由于对Unix及Linux系统的任何版本,vi编辑器是完全相 ...

  8. IntelliJ IDEA 的使用方法总结

    创建普通 Java 项目 1.首次新建一个项目 如果是首次使用,在这个界面可以点击 Create New Project ,创建一个新项目. 选择Java,然后选好 JDK 的位置,接着点击下一步 N ...

  9. Day3:html和css

    Day3:html和css 多类名选择器 样式的显示效果是跟html元素中的类名先后顺序无关,而是跟css样式的书写上下顺序有关. <!DOCTYPE html> <html lan ...

  10. Python学习笔记【第十三篇】:Python网络编程一Socket基础

    什么是⽹络 网络能把双方或多方连在一起的工具,即把数据从一方传递到另一方进行数据传递. 网络编程就是不同电脑上的软件能够进行数据传递.即进程间的通讯. 什么是TCP/IP协议 协议就是大家一起遵守的约 ...