高性能Mysql笔记 — explain

explain

查看sql的执行计划,只是一个近似结果,一般不会实际执行该sql,如果有子查询就会执行子查询
explain table_name,这儿的table_name含义较广:子查询、union结果

两个变种:
explain extended:可以查看将执行计划生成的sql语句,将要被废弃
explain partitions:显示查询将访问的分区

explain的局限:

  • 不会告诉你触发器、存储过程和UDF对如何影响查询结果
  • 不会告诉你mysql执行查询过程中做的特定优化
  • 不会包含执行计划的所有信息
  • 不区分相同名字的事物,例如:内存和排序和临时文件都使用"filesort",磁盘上和内存中的临时表都是用"Using tamporary"
  • 可能会误导,例如:可能会对一个很小的limit查询显示全索引扫描
  • 只能解释select查询(5.6以后允许解释非select语句),不会对存储过程调用、insert、update、delete或其他语句做解释,但是可以把这些语句使用select重写

id

select的编号,如果有子查询,则按照子查询在sql中出现的顺序编号,子查询一般包含:

  1. 一般子查询,子查询位于select字段位置
  2. 派生表,位于from 子句中的查询
  3. union查询

select_type

表示查询的类型

  • simple,简单子查询,不包含子查询和union
  • primary,包含union或者子查询,最外层的部分标记为primary
  • subquery,一般子查询中的子查询被标记为subquery,也就是位于select列表中的查询
  • derived,派生表——该临时表是从子查询派生出来的,位于form中的子查询
  • union,位于union中第二个及其以后的子查询被标记为union,第一个就被标记为primary,如果是union位于from中则标记为derived
  • union result,用来从匿名临时表里检索结果的select被标记为union result
    subquery和union还可以被标记为dependent和uncacheable

table

对应行正在访问哪一个表,表名或者别名

  • 关联优化器会为查询选择关联顺序,左侧深度优先
  • 当from中有子查询的时候,表名是derivedN的形式,N指向子查询,也就是explain结果中的下一列
  • 当有union result的时候,表名是union 1,2等的形式,1,2表示参与union的query id

type

访问类型,mysql如何查找表中的行

  • all,逐行全表扫描,如果使用了limit,extra中显示Using distinct/not exists
  • index,按照索引全表扫描,根据扫描结果随机访问行,开销较大,如果使用覆盖索引开小会小一点,这是extra显示using index
  • range,范围扫描就是一个有限制的索引扫描,开始于索引的某一行,返回匹配这个值域的行,比如:between,where里面的>,in、or也显示为range,但是相差较大的类型
  • ref,索引查找,返回匹配单个值的行,这个值是一个常数或者多表查询里前一个查询的结果
  • eq_ref,最多只返回一条记录,例如:主键或者唯一值索引查找
  • const,system,mysql将某一部分优化为一个常量,提高效率
  • null,意味着mysql在优化阶段分解语句,在执行阶段不需要再访问表或者索引

possible_key

显示查询使用了哪些索引,表示该索引可以进行高效地查找,但是列出来的索引对于后续优化过程可能是没有用的

key

显示mysql决定采用哪一列来优化对该表的访问,表示该索引可以最小化查询成本

key_len

索引使用的字节数,可以估算出具体是哪些列

ref

显示key列中记录的索引查找值所用的列或者常量

rows

mysql估计所需要查找的行数

extra

显示的是不适合在其他列里面显示的信息

  • using index,使用覆盖索引
  • using where,mysql将在存储引擎检索后再进行过滤
  • using temporary,使用临时表对查询结果进行排序
  • using filesort,使用外部索引对结果进行排序,而不是按照索引从表里读取,不能说明使用哪一种排序,也不能说明是在磁盘上还是内存中排序
posted @ 2017-04-21 00:30  lacker  阅读(1083)  评论(0编辑  收藏  举报