大白话讲解mysql执行计划

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 干货

MySQL执行计划分析

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

(root@localhost) [(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
  • unin/union all
  • group by
  • distinct
  • 聚合函数
  • limit
  • @
  • 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
  • materialized
  • select /*+ semijoin(@sub MATERIALIZATION) / * from t_order t2 where t2.emp_no in (select /+ QB_NAME(sub) */ t1.emp_no from dept_emp t1);
  • 物化,5.7开始in会产生,也会生成auto_key索引
  • in中使用hint QB_NAME,外层使用这个hint

1.3 table

  • NULL
  • 表示不使用任何表
  • 使用dual
  • extra中出现select tables optimized away,多见于count操作
  • 表名或者表的别名
  • <derived+ 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;
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
SQL 关系型数据库 MySQL
MySQL视图、索引、备份与恢复、执行计划(三)
MySQL视图、索引、备份与恢复、执行计划(三)
59 0
|
5天前
|
SQL 存储 关系型数据库
深入 MySQL 的执行计划与性能优化
深入 MySQL 的执行计划与性能优化
13 0
|
4月前
|
SQL 关系型数据库 MySQL
【Mysql】 深入理解MySQL的执行计划
【Mysql】 深入理解MySQL的执行计划
143 4
|
4月前
|
SQL 关系型数据库 MySQL
MySQL数据库——索引(4)-SQL性能分析-profile详情、explain(profile查看指令,explain执行计划中各个字段的含义)
MySQL数据库——索引(4)-SQL性能分析-profile详情、explain(profile查看指令,explain执行计划中各个字段的含义)
48 2
|
5月前
|
SQL 算法 关系型数据库
从执行计划了解MySQL优化策略
从执行计划了解MySQL优化策略
75 0
从执行计划了解MySQL优化策略
|
5月前
|
关系型数据库 MySQL 数据库
mysq优化---mysql执行计划解释、优化查询、数据库结构、服务器
mysq优化---mysql执行计划解释、优化查询、数据库结构、服务器
|
5月前
|
存储 关系型数据库 MySQL
MySQL查询执行计划详解(EXPLAIN)
一、单表查询 访问方法/访问类型: • const:通过主键值或唯一二级索引与一个常熟进行等值查询(不包括NULL),只会生成一条记录 • ref:普通二级索引与一个常数进行等值比较,可能生成多条记录 • ref_or_null:ref的前提下可以加上or key is null • range:对应的扫描区间为若干个单点扫描区间或范围扫描区间(不包括负无穷到正无穷的范围) • index:扫描区间为全表,但是可以在二级索引中扫描(因为二级索引每条记录占用空间更小,所以需要读的页更少) • all:直接扫描全部的聚集索引记录
|
11月前
|
关系型数据库 MySQL 索引
Mysql的执行计划explain
Mysql的执行计划explain
53 0
|
存储 关系型数据库 MySQL
MySQL基础应用拓展、索引及执行计划
MySQL基础应用拓展、索引及执行计划
76 0
MySQL基础应用拓展、索引及执行计划
|
存储 关系型数据库 MySQL
MySQL视图、索引、备份与恢复、执行计划(二)
MySQL视图、索引、备份与恢复、执行计划(二)
68 0
下一篇
无影云桌面