mysql执行计划学习

mysql执行计划

前言

日常工作中,发现一些sql查询速度过慢,就会使用explain来查看执行计划,用以优化sql语句,用法如下:

示例图片

主要列详解

1.id

select 查询的序列号,表示查询中执行select子句或操作表的顺序

id有三种情况:

  • id相同,执行顺序由上到下

    执行顺序相同

总结:加载顺序由上到下

  • id不同,子查询的话id序号会递增

执行顺序不同

总结:执行顺序不同时,id值越大,优先级越高

  • 上面两种情况同时存在

    总结:id值相同认为是同一组,从上到下执行;在所有组中,id越大,优先级越高

2.select_type

表示select语句的类型

select_typeMeaning
SIMPLE简单查询,不使用union或者子查询
PRIMARY最外层的查询
UNIONunion语句中第二个以上的select语句
DEPENDENT UNIONunion语句中第二个以上的select语句,依赖子查询
UNION RESULTunion查询的结果
SUBQUERY子查询中的第一个select语句
DEPENDENT SUBQUERY子查询中的第一个SELECT,依赖于外面的查询
DERIVED导出表的SELECT(FROM子句的子查询)
MATERIALIZED物化子查询
UNCACHEABLE SUBQUERY无法缓存结果的子查询,必须为外部查询的每一行重新计算
UNCACHEABLE UNIONUNION 属于不可缓存的子查询的第二个或后一个选择

3.table

输出行的引用名称,可以是以下值:

  • <unionM,N>:指id为M和N的集合

  • <derived**N**>:用于与该行的派生表结果id的值 N。例如,派生表可以来自FROM子句中的子查询

  • <subquery**N**>:id 值为的行的具体化子查询的结果N

4.partitions

记录与查询匹配的分区,非分区表显示为NULL

5.type

type字段解释表示怎么连接的,以下列表描述从最好到最差的连接类型:

  • system
    表只有一行数据(例如:系统表),这是const连接的特例

  • const

    表至多有一条匹配行,,const类型链接的表非常快,因为只读一次

    example:
    SELECT * FROM tbl_name WHERE primary_key=1;
    
    SELECT * FROM tbl_name
      WHERE primary_key_part1=1 AND primary_key_part2=2;
    
  • eq_ref

    eq_ref在连接操作时使用索引的所有部分并且索引是主键或者唯一键时被使用,只会从连接好的表记录中取一条记录

    example:
    SELECT * FROM ref_table,other_table
      WHERE ref_table.key_column=other_table.column;
    
    SELECT * FROM ref_table,other_table
      WHERE ref_table.key_column_part1=other_table.column
      AND ref_table.key_column_part2=1;
    
  • ref

    ref用户最左前缀或者键不是主键(换句话说,连接无法根据键值选择一行记录),会取出所有匹配到的记录

    example:
    SELECT * FROM ref_table WHERE key_column=expr;
    
    SELECT * FROM ref_table,other_table
      WHERE ref_table.key_column=other_table.column;
    
    SELECT * FROM ref_table,other_table
      WHERE ref_table.key_column_part1=other_table.column
      AND ref_table.key_column_part2=1;
    
  • fulltext

    使用FULLTEXT索引执行引擎

  • ref_or_null

    类似ref,不过会额外搜索包含NULL值的行,这个通常用于子查询的优化

    example:
    
    SELECT * FROM ref_table
      WHERE key_column=expr OR key_column IS NULL;
    
  • index_merge

    表示使用联合索引

  • unique_subquery

    这个类型在以下IN 子查询中替换eq_ref,只是一个索引查找函数,来替换子查询获取更好的效果

    example:
    
    value IN (SELECT primary_key FROM single_table WHERE some_expr)
    
  • index_subquery

    类似unique_subquery,只对以下形式的非唯一索引有效

    example:
    
    value IN (SELECT key_column FROM single_table WHERE some_expr)
    
  • range

    使用索引选择行,只检索给定范围内的行。key列显示使用了哪个索引,一般就是在你的where语句中出现 =<>,>,>=,<,<=,is_null,<>,between,like or in() 等的查询

    example:
    
    SELECT * FROM tbl_name
      WHERE key_column = 10;
    
    SELECT * FROM tbl_name
      WHERE key_column BETWEEN 10 and 20;
    
    SELECT * FROM tbl_name
      WHERE key_column IN (10,20,30);
    
    SELECT * FROM tbl_name
      WHERE key_part1 = 10 AND key_part2 IN (10,20,30);
    
  • index

    FULL INDEX SCAN,index与all区别是index类型只遍历索引树,all全表

  • all

    FULL TABLE SCAN全表遍历

possible_keys

表示查询时,能够使用的索引.不一定表示数据库查询的时候会真正用到,具体使用哪个索引由key字段决定

key

此字段是 MySQL 在当前查询时所真正使用到的索引.

key_len

表示查询优化器使用了索引的字节数. 这个字段可以评估组合索引是否完全被使用, 或只有最左部分字段被使用到

rows

MySQL 查询优化器根据统计信息, 估算 SQL 要查找到结果集需要扫描读取的数据行数.
这个值非常直观显示 SQL 的效率好坏, 原则上 rows 越少越好.

参考文档