mysql执行计划简介
介绍
本篇主要通过汇总网上的大牛的知识,简单介绍一下如何使用mysql的执行计划,并根据执行计划判断如何优化和是否索引最优。
执行计划可显示估计查询语句执行计划,从中可以分析查询的执行情况是否最优,有助于对不使用索引的语句进行优化。EXPLAIN对每个查询返回一行信息,列出了有序的表格,MySQL处理语句的时候读取他们。MySQL解决所有的连接使用嵌套连接方法。这意味读取第一张一行,然后匹配第二张表的所有行,第三张表甚至更多表。当所有的表在处理时,MySQL会输出已经查询出来的列,并且回溯到表继续查找直到所有的行被找到,从该表读取下一行,直到程序继续处理下一张表。
使用关键词 EXTENDED ,EXPLAIN 会处理通过 SHOW WARNINGS 看到的一些额外信息。EXPLAIN EXTENDED 会显示这些滤出的列。
语法:
EXPLAIN <select statement>;
输出表格字段如下:
mysql> explain select * from mysql.user where user='root';
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| | SIMPLE | user | ALL | NULL | NULL | NULL | NULL | | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
|
Column |
JSONName |
Meaning |
|---|---|---|
|
|
|
查询标识。id越大优先执行;id相同自上而下执行; |
|
|
None |
查询的类型 |
|
|
|
查询的表 |
|
|
|
Thematching partitions |
|
|
|
连接类型 |
|
|
|
可能选择的索引 |
|
|
|
实际使用的索引 |
|
|
|
使用的索引长度 |
|
|
|
哪一列或常数在查询中与索引键列一起使用 |
|
|
|
估计查询的行数 |
|
|
|
被条件过滤掉的行数百分比 |
|
|
None |
解决查询的一些额外信息 |
以下主要举例说明3个字段:select_type 、type、Extra
【select_type】
|
alue |
JSONName |
Meaning |
|---|---|---|
|
|
None |
|
|
|
None |
|
|
|
None |
|
|
|
|
|
|
|
|
|
|
|
None |
子查询中第一个SELECT |
|
|
|
子查询中第一个SELECT,独立于外部查询 |
|
|
None |
子查询在 FROM子句中 |
|
|
|
物化子查询(不清楚是什么样的查询语句?) |
|
|
|
结果集不能被缓存的子查询,必须重新评估外层查询的每一行 |
|
|
|
|
创建测试表:
create table tabname (
id int auto_increment not null primary key,
name varchar() null,
indate datetime null,
tid int null,
key(tid),
key(indate)
)engine=innodb; create table tabname2 (
id int auto_increment not null primary key,
name varchar() null,
indate datetime null,
tid int null,
key(tid),
key(indate)
)engine=myisam; insert into tabname(name,indate,tid) values('love',now(),),('lucky',now(),),('passion',now(),);
insert into tabname2(name,indate,tid) values('love',now(),),('lucky',now(),),('passion',now(),);
#SIMPLE
#PRIMARY / DERIVED
mysql> explain select * from (select * from tabname) as a;
+----+-------------+------------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+------+---------------+------+---------+------+------+-------+
| | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | | |
| | DERIVED | tabname | ALL | NULL | NULL | NULL | NULL | | |
+----+-------------+------------+------+---------------+------+---------+------+------+-------+
#PRIMARY / UNION / UNION RESULT
mysql> explain select * from tabname where id=(select max(id) from tabname);
+----+-------------+---------+-------+---------------+---------+---------+-------+------+------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+---------+---------+-------+------+------------------------------+
| | PRIMARY | tabname | const | PRIMARY | PRIMARY | | const | | |
| | SUBQUERY | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away |
+----+-------------+---------+-------+---------------+---------+---------+-------+------+------------------------------+
#PRIMARY / SUBQUERY
#PRIMARY / DEPENDENT SUBQUERY
mysql> explain select * from tabname a where exists(select from tabname b where a.id=b.id);
mysql> explain select *,(select name from tabname b where a.id=b.id) from tabname a;
mysql> explain select * from tabname where id not in(select id from tabname);
+----+--------------------+---------+-----------------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+---------+-----------------+---------------+---------+---------+------+------+-------------+
| | PRIMARY | tabname | ALL | NULL | NULL | NULL | NULL | | Using where |
| | DEPENDENT SUBQUERY | tabname | unique_subquery | PRIMARY | PRIMARY | | func | | Using index |
+----+--------------------+---------+-----------------+---------------+---------+---------+------+------+-------------+
#PRIMARY / DEPENDENT UNION / DEPENDENT SUBQUERY / UNION RESULT
mysql> explain select * from tabname where id in (select id from tabname union select id from tabname);
+----+--------------------+------------+--------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+------------+--------+---------------+---------+---------+------+------+-------------+
| | PRIMARY | tabname | ALL | NULL | NULL | NULL | NULL | | Using where |
| | DEPENDENT SUBQUERY | tabname | eq_ref | PRIMARY | PRIMARY | | func | | Using index |
| | DEPENDENT UNION | tabname | eq_ref | PRIMARY | PRIMARY | | func | | Using index |
| NULL| UNION RESULT | <union2,> | ALL | NULL | NULL | NULL | NULL | NULL | |
+----+--------------------+------------+--------+---------------+---------+---------+------+------+-------------+
【type】
|
type |
Meaning |
|---|---|
|
|
表仅一行数据 (=system table).这是const连接类型的特例。 |
|
|
|
|
|
|
|
|
对于前面表的结果集匹配查询的所有行,当连接使用索引key时,或者索引不是 |
|
|
|
|
|
使用全文索引时出现。 |
|
|
使用了索引合并优化。(未成功) |
|
|
该类型将ref替换成以下子查询的格式: valueIN (SELECTprimary_key FROMsingle_table WHERE some_expr) |
|
|
与 valueIN (SELECTkey_columnFROMsingle_table WHERE some_expr) |
|
|
使用索引检索给定范围内的行。 |
|
|
|
|
|
对于前面表的结果集中,进行了全表扫描。最差的一种类型,应考虑查询优化了! |
查询类型性能由优到差:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
#system
#const
mysql> explain select * from tabname as a,tabname as b where a.id=b.id and a.id=;
mysql> explain select * from tabname where id=;
+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------+
| | SIMPLE | tabname | const | PRIMARY | PRIMARY | | const | | |
+----+-------------+---------+-------+---------------+---------+---------+-------+------+-------+
#eq_ref(engine=myisam)
mysql> explain select * from tabname2 as a,tabname2 as b where a.id=b.id;
+----+-------------+-------+--------+---------------+---------+---------+-----------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------+---------+---------+-----------+------+-------+
| | SIMPLE | a | ALL | PRIMARY | NULL | NULL | NULL | | |
| | SIMPLE | b | eq_ref | PRIMARY | PRIMARY | | test.a.id | | |
+----+-------------+-------+--------+---------------+---------+---------+-----------+------+-------+
#ref
#ref_or_null
mysql> explain select id,tid from tabname where tid= or tid is null;
+----+-------------+---------+-------------+---------------+------+---------+-------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------------+---------------+------+---------+-------+------+--------------------------+
| | SIMPLE | tabname | ref_or_null | tid | tid | | const | | Using where; Using index |
+----+-------------+---------+-------------+---------------+------+---------+-------+------+--------------------------+
#fulltext
#index_merge(未成功)
#unique_subquery
#index_subquery
mysql> explain select * from tabname where tid in(select tid from tabname);
mysql> explain select * from tabname where id in(select tid from tabname);
+----+--------------------+---------+----------------+---------------+------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+---------+----------------+---------------+------+---------+------+------+--------------------------+
| | PRIMARY | tabname | ALL | NULL | NULL | NULL | NULL | | Using where |
| | DEPENDENT SUBQUERY | tabname | index_subquery | tid | tid | | func | | Using index; Using where |
+----+--------------------+---------+----------------+---------------+------+---------+------+------+--------------------------+
#range
mysql> explain select * from tabname where tid between and ;
mysql> explain select * from tabname where id>;
+----+-------------+---------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+---------+---------+------+------+-------------+
| | SIMPLE | tabname | range | PRIMARY | PRIMARY | | NULL | | Using where |
+----+-------------+---------+-------+---------------+---------+---------+------+------+-------------+
#index
mysql> explain select id,tid from tabname;
mysql> explain select tid from tabname;
+----+-------------+---------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+------+---------+------+------+-------------+
| | SIMPLE | tabname | index | NULL | tid | | NULL | | Using index |
+----+-------------+---------+-------+---------------+------+---------+------+------+-------------+
#ALL
mysql> explain select * from tabname where tid<>;
mysql> explain select * from tabname;
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
| | SIMPLE | tabname | ALL | NULL | NULL | NULL | NULL | | |
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
【Extra】
该列输出关MySQL如何解决查询的额外信息。(下面列出部分常见的)
|
Extra |
Meaning |
|---|---|
|
|
使用过滤条件 |
|
|
|
|
|
|
|
|
没有groupby情况下使用min(),max(),或者count(*) |
|
|
|
|
|
在leftjoin中匹配一行之后将不再继续查询查询 |
|
|
查找到第一个匹配的行之后,MySQL则会停止对当前行的搜索 |
|
|
where子句总数失败的查询 |
|
|
|
|
|
使用连接缓存 |
|
|
|
#using where
mysql> explain select * from tabname where id>;
mysql> explain select * from tabname where tid=;
+----+-------------+---------+------+---------------+------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+------+---------+-------+------+-------------+
| | SIMPLE | tabname | ref | tid | tid | | const | | Using where |
+----+-------------+---------+------+---------------+------+---------+-------+------+-------------+
#using index
mysql> explain select tid from tabname;
+----+-------------+---------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+------+---------+------+------+-------------+
| | SIMPLE | tabname | index | NULL | tid | | NULL | | Using index |
+----+-------------+---------+-------+---------------+------+---------+------+------+-------------+
#using temporary
mysql> explain select distinct name from tabname;
+----+-------------+---------+------+---------------+------+---------+------+------+-----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+------+---------+------+------+-----------------+
| | SIMPLE | tabname | ALL | NULL | NULL | NULL | NULL | | Using temporary |
+----+-------------+---------+------+---------------+------+---------+------+------+-----------------+
#select tables optimized away
mysql> explain select max(tid) from tabname;
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
| | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
#using filesort
mysql> explain select id,name from tabname group by id,name;
mysql> explain select * from tabname order by name;
+----+-------------+---------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+------+---------+------+------+----------------+
| | SIMPLE | tabname | ALL | NULL | NULL | NULL | NULL | | Using filesort |
+----+-------------+---------+------+---------------+------+---------+------+------+----------------+
#not exists
#distinct
#impossible where
#impossible having
mysql> explain select id,count(*) from tabname group by id having =;
mysql> explain select count(*) from tabname having =;
+----+-------------+-------+------+---------------+------+---------+------+------+-------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------------+
| | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Impossible HAVING |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------------+
现在使用 EXTENDED 情况:
语法:
- EXPLAIN EXTENDED <select statement>;
不使用 extended 和使用extended 的分析情况:
可以看到,使用 extended 时,输出的最下面多了 1 条警告。 此时可以用 show warnings
来查看:
show warnings 显示了优化器中是怎么规范表和字段名的,在通过重写和优化规则之后的 select 语句是什么样子。
更多参考:
EXPLAIN EXTENDED Output Format
mysql执行计划简介的更多相关文章
- MySQL执行计划解读
Explain语法 EXPLAIN SELECT …… 变体: 1. EXPLAIN EXTENDED SELECT …… 将执行计划“反编译”成SELECT语句,运行SHOW WARNINGS 可得 ...
- mysql执行计划
烂sql不仅直接影响sql的响应时间,更影响db的性能,导致其它正常的sql响应时间变长.如何写好sql,学会看执行计划至关重要.下面我简单讲讲mysql的执行计划,只列出了一些常见的情况, ...
- 如何查看MySQL执行计划
在介绍怎么查看MySQL执行计划前,我们先来看个后面会提到的名词解释: 覆盖索引: MySQL可以利用索引返回select列表中的字段,而不必根据索引再次读取数据文件 包含所有满足查询需要的数据的索引 ...
- mysql 执行计划的理解
1.执行计划就是在sql语句之前加上explain,使用desc 也可以.2.desc有两个选项extended和partitions,desc extended 将原sql语句进行优化,通过show ...
- MySQL执行计划 EXPLAIN参数
MySQL执行计划参数详解 转http://www.jianshu.com/p/7134286b3a09 MySQL数据库中,在SELECT查询语句前边加上“EXPLAIN”或者“DESC”关键字,即 ...
- 查看Mysql执行计划
使用navicat查看mysql执行计划: 打开profile分析工具: 查看是否生效:show variable like ‘%profil%’; 查看进程:show processlist; 选择 ...
- MySQL 执行计划explain详解
MySQL 执行计划explain详解 2015-08-10 13:56:27 分类: MySQL explain命令是查看查询优化器如何决定执行查询的主要方法.这个功能有局限性,并不总会说出真相,但 ...
- MYSQL 执行计划
Explain语法 EXPLAIN SELECT …… 变体: 1. EXPLAIN EXTENDED SELECT …… 将执行计划“反编译”成SELECT语句,运行SHOW WARNINGS 可得 ...
- MySQL执行计划extra中的using index 和 using where using index 的区别
本文出处:http://www.cnblogs.com/wy123/p/7366486.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错 ...
随机推荐
- 原创~vue router-link添加点击事件
在学习vue中会遇到给router-link添加@click,@mouseover等事件 我想要做的是用v-for循环输出导航菜单,但是下面代码的@click事件和@mouseover并不会响应 &l ...
- OKL4虚拟化技术跟踪
这篇博客准备介绍OKL4的研究进展,本文的内容主要根据我个人阅读<OKL4_LongPaper_2010_HW_VM>这篇文章之后的理解,我也根据这篇论文的内容做了一些实验,奈何此论文涉及 ...
- javascript正则表达式的一些笔记
正则表达式:Regular Expression.使用单个字符串来描述,匹配一系列符合某个句法规则的字符串.即按照某种规则去匹配符合条件的字符串.正则表达式就是规则. \b 单词边界 regexp对象 ...
- Kubernetes 使用私服镜像
非常感谢这些无私知识分享的同僚 重要参考:http://blog.csdn.net/u013812710/article/details/52766227 1.首先你得有个私库,这里我用的是阿里云私库 ...
- [Note] Yet Another Resource Negotiator
Yet Another Resource Negotiator Apache Hadoop YARN 是新一代资源管理调度框架,主要针对 Hadoop MapReduce 1.0 的缺陷做出了改进 M ...
- 高并发场景下的httpClient优化使用
1.背景 我们有个业务,会调用其他部门提供的一个基于http的服务,日调用量在千万级别.使用了httpclient来完成业务.之前因为qps上不去,就看了一下业务代码,并做了一些优化,记录在这里. 先 ...
- php程序员的成长之路
第一阶段:基础阶段(基础PHP程序员) 重点:把LNMP搞熟练(核心是安装配置基本操作) 目标:能够完成基本的LNMP系统安装,简单配置维护:能够做基本的简单系统的php开发:能够在PHP中型系统中支 ...
- 多项式A除以B
这个问题我是在PAT大区赛题里遇见的.题目如下: 多项式A除以B(25 分) 这仍然是一道关于A/B的题,只不过A和B都换成了多项式.你需要计算两个多项式相除的商Q和余R,其中R的阶数必须小于B的阶数 ...
- C语言视频简介
通过学习<C语言基础视频教程>,可以让你对C语言有一个基础的了解,并且会编写一些基础的程序,本次视频主要讲解的内容有: 1. 数字的进制转换 2. 变量.运算符和表达式 3. 流程控制语句 ...
- linux lnmp搭建及解释
lnmp的搭建linux nginx mysql(mariaDB) php 安装mysql依赖:yum -y install cmake(cmake编译工具)yum -y install gcc gc ...