mysql 执行计划

mysql 执行计划只需要在需要执行的语句前加上EXPLAIN关键字就可以查看执行计划了如表

explain select name, nickname, ctime from dt_user where city = 'shanghai' order by name;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE dt_user range PRIMARY idx_city_name 2945 NULL 55183 Usingindexcondition

官方文档:https://dev.mysql.com/doc/refman/8.0/en/explain-output.html

输出参数

id

  • select查询序列号
  • id相同,执行顺序由上至下;id不同,id值越大优先级越高,越先被执行

select_type

name 描述
simple 简单查询,不包含只查询或union
primary 包含复杂的子查询,最外层查询标记为该值
subquery 在select或where里包含子查询,被标记为该值
derived 在from列表中包含的子查询被标记为该值,Mysql会递归执行这些子查询,吧结果放在临时表
union 若第二个select出现在union之后,则被标记为该值
union result 从union表获取结果的select

type

表的连接类型,其值、性能由高到底排列如下

name 描述
system 表中只有一行数据,相当于系统表
const 通过索引一次就找到,只匹配一行数据
eq_ref 唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配,常见于主键或唯一索引扫描
ref 非唯一性索引扫描,返回匹配某个单独值的所有行,用于=、< 或 > 操作符带索引的列
fulltext 连接是使用FULLTEXT 索引执行的。
ref_or_null 这种连接类型类似于 ref,但另外 MySQL 会额外搜索包含NULL值的行。这种连接类型优化最常用于解析子查询。
index_merge 此连接类型表明使用了索引合并优化。在这种情况下,key输出行中的列包含所用索引的列表,并 key_len包含所用索引的最长键部分的列表
unique_subquery 此类型替换 以下形式eq_ref的某些 IN子查询,unique_subquery只是一个索引查找功能,完全替代子查询以提高效率。
index_subquery 此连接类型类似于 unique_subquery. 它替换IN子查询,但它适用于以下形式的子查询中的非唯一索引
range 索引范围扫描,对索引的扫描开始于某一点,返回匹配值域的行,常见于between、<、>等的查询
index Full Index Scan,index与ALL区别为index类型只遍历索引树
ALL Full Table Scan, MySQL将遍历全表以找到匹配的行

越上面越好,前5种情况都是理想的索引的情况。通常优化至少到range级别,最好能优化到ref。

extra

包含不适合在其他列中显示但十分重要的额外信息。常见的值如下

name 描述
using filesort Mysql会对数据使用一个外部的索引排序,而不是安装表内的索引顺序进行读取,若出现该值,应该优化SQL语句
using temporary 使用临时表存储中间结果,比如Mysql在对查询结果排序时使用临时表,常见于order by 和 group by,应该优化SQL语句
using index 表示select操作使用了覆盖索引,避免了访问表的数据行,效率不错
using where where子句用于限制哪一行
using join buffer 使用连接缓存
distinct 发现第一个匹配后,停止为当前的行组合搜索更多的行