20180925 更新:
由于这篇文章基本是参考的网上的信息整理而成,再次翻阅感觉某些东西解释的不算清楚,所以趁着今天有那么一点点的时间再把语言重新组织一下,内容均来源于书籍《深入浅出MySQL: 数据库开发、优化与管理维护》,同时搞 DBA 或者经常使用 MySQL 开发的同仁建议你们购买看看,也还是很有帮助滴。
—————-丑逼分割线—————-
不管他三七二十一,再次开一个坑,这次开始坑 MySQL,随着工作经验的不断积累,sql 语句再也不能 xjb 写了,总是要注意优化,注意效率,注意规范,在sql优化的过程中我们不可避免的要使用 explain 命令来查看自己写的 sql 是如何执行的,查看使用了什么索引,全表扫描还是索引扫描等。对于刚开始接触的时候,一小部分人可能对 explain 的各个字段的含义有不清楚的地方,于是记录一下,也留待我日后复习使用。废话少说,先上一张结果图,工具为 Navicat。
当我们定位到执行效率低的 SQL 语句之后,我们可以通过 EXPLAIN 或者 DESC 命令来查看 MySQL 到底是如何解析并执行 SELECT 等语句的。当你点击那个解释按钮的时候或者将你的 SQL 前面加上「explain」命令,MySQL 就为你显示以上一张表的查询结果,今天要记录的就是 explain 命令执行之后各个字段的都有哪些值,这些值都是什么含义,这些字段又都是表达什么特征的。来一张表,直观一点。
字段名称
|
字段含义
|
字段值及其含义
|
id
|
查询序列号,explain 解释这条 sql 的
查询序列号
|
无
|
select_type
|
表示 select 的类型,查询类型
|
simple:简单查询,即不使用 union 或者子查询
primary:主查询,即外层的 select 查询
union:union 中第二个或者后面的 select 查询语句
dependentunion:同上,但是取决于外层的 select
union result:union 的结果
subquery:子查询中的第一个 select 查询语句
dependent subquery:同上,但是取决于外层的 select
derived:导出表的 select,子查询
(可能看不太懂,其实我也不太懂,大概理解就行,他就是告诉你当前的 sql 是怎么查询数据的)
|
table
|
就是查询都去用了那几张表,在你的语句中都已经有所体现了
|
输出结果集的表 |
partitions
|
代表表使用的分区,关于 MySQL 表分区,你可以简单理解为为了存储数据,MySQL
将数据按照水平或者垂直将表分区存储,查询的时候从相应的区块中取出来
|
|
type
|
表示 MySQL 在表中找到所需行的方式,或者叫访问类型,以下类型从左到右性能由最差到最好: ALL->index->range->ref->eq-ref->const ->system->NULL
|
system:单表中最多有一个匹配行,查询起来非常迅速,所以这个匹配行中的其他列的值可以被优化器在当前查询中当作常量来处理。
const:上面的 system 就属于 const 的特例,描述的是表只有一行数据,在查询开始的时候就被读取
eq_ref:类似 ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配;简单来说,就是多表连接中使用 primary_key(主键)或者 unique_index 作为关联条件。
ref:使用非唯一索引扫描的前缀扫描,返回匹配某个单独的记录行,ref 还经常出现在 join 中。
ref_or_null:与ref 类似,区别在于条件中包含对 NULL 的查询
index_merge:索引合并优化
unique_subquery:in 的后面是一个查询主键字段的子查询
index_subquery:与 unique_subquery 类似,区别在于 in 的后面是查询非唯一索引字段的子查询
range:索引范围扫描,常见于 <、≤、>、≥、between 等操作符
index:索引全扫描,MySQL 遍历整个索引来查询匹配的行
ALL:全表扫描,MySQL 遍历全表来找到匹配的行
NULL:MySQL 不用访问表或者索引,直接就能够得到结果。
|
possible_keys
|
表示查询时可能使用的索引
|
|
key
|
表示实际使用的索引
|
|
key_len
|
使用到索引字段的长度
|
|
ref
|
告诉你除了索引以外,他还用了那个列帮你查询数据
|
|
rows
|
扫描行的数量
|
|
filtered
|
告诉你通过你的 where 条件它帮你过滤的多少没必要的数据的百分比
|
|
extra
|
执行情况的说明和描述,包含不适合在其他列中显示但是对执行计划非常重要的额外信息
|
distinct:发现第一个匹配行之后就停止匹配
not exists:为左连接查询优化,发现一个左连接的匹配的行就停止
range checked for each record(index map):没有好的索引可以使用
using filesort:按排序检索
using index:只查索引
using temporary:为了解决查询,MySQL 需要创建一个临时表帮助解决问题
using where:使用 where 条件来限制数据行或者其他数据表的查询
using sort_union,using union,using interesect,这些都是函数,告诉你他们试如何为索引合并服务的
using index for group by:同 using index,但是恰巧还可以用在 group by 的列上面
|
除此以外,还有 explain extended 命令,通过该命令再加上 show warnings,我们可以看到 SQL 执行之前优化器对 SQL 做了哪些 SQL 的优化以及改写,最早 filtered 字段就是在 extended 中,但是现在 explain 中也有体现了,比如我们经常用到 1=1 的恒等条件都会被优化器自动去掉等。
相关文章阅读
- 《浅析 MySQL 中的锁》
- 《MySQL 索引知识详细总结》
- 《如何彻底解决mysql.sock(Can’t connect to local MySQL server through)丢失的问题?非网上各种瞎哔哔的解决方式》
- 《阿里巴巴Java开发手册第五章MySQL数据库-索引规约篇》