MySQL执行计划复习

MySQL执行计划分析

Ⅰ、认识执行计划的每个字段

([email protected]) [(none)]> desc select 1;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra          |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+
|  1 | SIMPLE      | NULL  | NULL       | NULL | NULL          | NULL | NULL    | NULL | NULL |     NULL | No tables used |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+
1 row in set, 1 warning (0.00 sec)

1.1 id

  • 单纯的join,id都是1,且从上到下
  • subquery、scala subquery都会使id递增

1.2 select type

  • simple

    • 不使用union或者subquery的简单query
    • 子查询被优化器打开,失效了
  • primary
    • 使用union结合select时,第一个select type
    • subquery的query
  • union
    • 使用union结合select除了第一个select type为primary,其余为union(extra中union result是union去掉重复值的临时表)
    • 5.7开始union all不会出现union result,因为不去重
  • subquery
    • 不是用在from后面的subquery
    • 和外部表无关联
    • subquery(标量子查询)执行计划没错误,不代表sql执行没错(不能超过1行数据,subquery return more than 1 row)
  • dependent subquery
    • 必须依附于外面的值
    • scala subquery(和外部有关系的标量子查询)
    • exists
  • derived
    • from位置之后的subquery
    • derived是生成在内存或者临时表空间中
    • 如果derived作驱动表时,要点是减少数据量
    • 当作被驱动表时产生auto_key索引,也是以减少数据量为目
    • 5.7中optimizer_switch=‘derived_merge=on‘可以把简单subquery打开成join
    • derived_merge为on时被驱动表的连接条件要有索引,为off时被驱动表结果集要小
    • 5.7的derived_merge可能导致子查询中order by失效
    • 5.7以下操作可以防止derived_merge
      • unin/union all
      • group by
      • distinct
      • 聚合函数
      • limit
      • @
  • materialized
    • 物化,5.7开始in会产生,叶会生成auto_key索引
    • in中使用hint QB_NAME,外层使用这个hint
      • select /+ semijoin(@sub MATERIALIZATION) / * from t_order t2 where t2.emp_no in (select /+ QB_NAME(sub) / t1.emp_no from dept_emp t1);

1.3 table

  • NULL

    • 表示不使用任何表
    • 使用dual
    • extra中出现select tables optimized away,多见于count操作
  • 表名或者表的别名
  • <derved + id><union + id>
    • 临时表<>里的数字是id列
    • tmp_table_size = max_heap_table_size适当调大

1.4 type

  • const

    • 使用primary key或者unique key取得一条数据
  • eq_ref
    • join,且满足被驱动表的连接条件unique key或者primary key
  • ref
    • 对索引列做等号判断
  • range
    • between in like > <
    • 和const的区别在于索引扫描范围不一样
  • index
    • 索引全扫描,比起表全扫描且order by的情情况,但是绝大部分情况下也是优化对象
    • 不能使用range,const,ref的情况下,且只查询索引列,即不回表,使用索引进行排序或者聚合即省略排序
    • 索引(a,b),select a from xxx where b = ‘‘; 即联合索引中前导列不在where条件中,且查询列在索引中
    • 在聚合运算中group by后面的列在索引或者primary key中,且查询列也在索引中
  • all
    • 全表扫描
    • 大表中查询超过一半以上的值,效果更好
    • 索引失效
      • 无索引
      • 对索引列加工
      • 索引列隐式类型转换
      • 对日期类型进行like ‘20xxx‘
      • 单列索引,对数字列进行like ‘30%‘

1.5 possible_keys

  • 列出可能用到的索引,对优化没什么帮助
  • 5.6之后开始支持auto_key
  • auto_key就是临时创建索引,需要消耗一些内存和cpu,对tmp_table_size,max_heap_table_size依赖较大
  • mysql列大小超过767个字节,无法生成auto_key
  • convert(xxx,数据类型,字符集)

1.6 key

  • sql用到的索引

1.7 key_len

  • 显示sql到底使用了多少索引

1.8 ref

  • 只有type是ref或者const才会出现内容,没啥用,不用管

1.9 rows

  • MySQL优化器根据统计信息预估出来的值,不准

1.10 filter

  • 和rows一样是预估值,非100的情况是extra有using where关键字,表示从存储引擎中拿到数据后再加工的比例
  • 5.7开始该值比较准确

1.11 Extra

  • Distinct

    • MySQL在join过程中取出一行之后查询另一个表时,碰到一行就停止,有点像exsits
    • 必须是join
    • distinct关键字
    • select列上只能含有驱动表的字段
    • 使用straight_join hint可以强制改变驱动表
  • select tables optimized away
    • 查询中只有min、max的时候出现,有时候count貌似也会出现
    • 联合主键,其中任一一个字段用等值查询,查出另一个字段的min或max,且不能包含group by
  • Using filesort
    • order by, group by且没使用索引
    • 8.0 group by不会出现
  • Using index
    • 只使用索引不回表就可以查到
    • 如果表对应的where条件选择率不是很好,且一行长度很长,此时课考虑创建包含对应列的索引达到减少物理io的目的
    • 延迟join必须使用using index,否则无效
  • Using temporary
    • sql执行过程中存储中间结果会使用tempoary table,但无法判断在内存还是disk
    • order by,group by未使用索引
    • 执行计划中的select type为derived
    • show swssion status like ‘%tmp%‘
    • max_heap_table_size和tmp_table_size(不一致时以小的为准)
  • Using where
    • 一般和filtered,rows一起看
    • 表示从存储引擎中拿到数据再过滤
    • rows是存储引擎中拿数据的预估值,filtered是再过滤的百分比
  • Using index condition
    • 必须是二级索引才有,且有索引后面部分无法使用时,回表次数很大,效果更好
    • optimizer_switch=‘index_condition_pushdown=on‘
  • Using MRR
    • optimizer_switdch=‘mrr_cost_based=0ff‘
    • 回表之前先排序,降低随机io
  • Range checked for each record
    • type为all
    • 这是优化对象,紧接着用show warnings来定位问题
  • Using join buffer(Block Nested Loop)
    • optimizer_switch=‘block_nested_loop=on,batched_key_access=on‘
    • 被驱动表没有索引且数据量较少的时候,一般这种情况也是优化对象

Ⅱ、获取运行中SQL的执行计划

desc for connection connection_id;

原文地址:https://www.cnblogs.com/---wunian/p/10060034.html

时间: 2024-11-05 14:40:29

MySQL执行计划复习的相关文章

MySQL执行计划解读

MySQL执行计划解读 http://www.cnblogs.com/ggjucheng/archive/2012/11/11/2765237.html MySQL执行计划解读 Explain语法 EXPLAIN SELECT -- 变体: 1. EXPLAIN EXTENDED SELECT -- 将执行计划"反编译"成SELECT语句,运行SHOW WARNINGS 可得到被MySQL优化器优化后的查询语句 2. EXPLAIN PARTITIONS SELECT -- 用于分区表

MySQL执行计划解读 转他人文章

Explain语法 EXPLAIN SELECT …… 变体: 1. EXPLAIN EXTENDED SELECT …… 将执行计划“反编译”成SELECT语句,运行SHOW WARNINGS 可得到被MySQL优化器优化后的查询语句 2. EXPLAIN PARTITIONS SELECT …… 用于分区表的EXPLAIN 执行计划包含的信息 id 包含一组数字,表示查询中执行select子句或操作表的顺序 id相同,执行顺序由上至下 如果是子查询,id的序号会递增,id值越大优先级越高,越

MySQL 执行计划explain详解

MySQL 执行计划explain详解 2015-08-10 13:56:27 分类: MySQL explain命令是查看查询优化器如何决定执行查询的主要方法.这个功能有局限性,并不总会说出真相,但它的输出是可以获取的最好信息,值得花时间去了解,因为可以学习到查询是如何执行的. 调用EXPLAIN 在select之前添加explain,mysql会在查询上设置一个标记,当执行查询计划时,这个标记会使其返回关于执行计划中每一步的信息,而不是执行它.它会返回一行或多行信息,显示出执行计划中的每一部

MySQL执行计划不准确 -概述

为毛 MySQL优化器的执行计划 好多时候都不准确,不是最优的呢(cpu+io)??? 因素太多了:: 存在information_schema的信息是定期刷新上去的,好多时候不是最真的,甚至相差好大(非高山峰时好好利用一下analyze table等): 现在一个企业有钱没地方花,买一大堆固态磁盘,碰巧非智能的MySQL不能很好滴跟上硬件优化的节奏,可能超过一部分的选择原理就不怎么准确了(这点相信其他数据库也是痛点吧); 环境因素/ 配置因素 等等 ... MySQL执行计划不准确 -概述,布

【转】mysql执行计划介绍

原文地址:http://www.jb51.net/article/43306.htm 1.查看mysql执行计划 explain SELECT * from shippingorder where STATUS<>4; 2.执行计划包含的信息 (1).id 含义,指示select字句或操作表的顺序. eg1:id相同,执行顺序从上到下,下面的执行计划表示,先操作t1表,然后操作t2表,最后操作t3表. eg2:若存在子查询,则子查询(内层查询)id大于父查询(外层查询),先执行子查询.id越大

MySQL执行计划 EXPLAIN参数

MySQL执行计划参数详解 转http://www.jianshu.com/p/7134286b3a09 MySQL数据库中,在SELECT查询语句前边加上“EXPLAIN”或者“DESC”关键字,即可查看该查询语句的执行计划,分析执行计划是优化慢查询的重要手段.如: EXPLAIN SELECT * FROM school; DESC SELECT * FROM school; 执行结果: 执行计划参数.png 接下来对这10个参数进行简单解释: 1.id:在整个查询中SELECT的位置: 2

如何查看MySQL执行计划

在介绍怎么查看MySQL执行计划前,我们先来看个后面会提到的名词解释: 覆盖索引: MySQL可以利用索引返回select列表中的字段,而不必根据索引再次读取数据文件 包含所有满足查询需要的数据的索引称为 覆盖索引(Covering Index) 如果要使用覆盖索引,一定要注意select列表中只取出需要的列,不可select *,因为如果将所有字段一起做索引会导致索引文件过大,查询性能下降 EXPLAIN查看执行计划的一些局限: EXPLAIN不会告诉你关于触发器.存储过程的信息或用户自定义函

MySQL执行计划的讲解

最近同事在执行线上执行一条MySQL的查询语句,数据的话在9000条左右,但使用左连接的时候查询速度大概在15秒左右~这速度确实是无法接受的~ 经过简单的修改,变为内连接的话,执行速度不到1秒. 下面是两条具体的sql: 左连接的sql如下: SELECT count(*) FROM investment i LEFT JOIN payment m ON m.bill_id = i.id; 执行结果如下: 使用内连接的sql如下: SELECT count(*) FROM investment

MySQL执行计划解读(转载)

MySQL执行计划解读 Explain语法 EXPLAIN SELECT …… 变体: 1. EXPLAIN EXTENDED SELECT …… 将执行计划“反编译”成SELECT语句,运行SHOW WARNINGS 可得到被MySQL优化器优化后的查询语句 2. EXPLAIN PARTITIONS SELECT …… 用于分区表的EXPLAIN 执行计划包含的信息 id 包含一组数字,表示查询中执行select子句或操作表的顺序 id相同,执行顺序由上至下 如果是子查询,id的序号会递增,