MySQL之EXPLAIN 执行计划详解
explain 可以分析 select 语句的执行,即 MySQL 的“执行计划。
一、type 列 MySQL 在表里找到所需行的方式。包括(由左至右,由最差到最好):
| All | index | range | ref | eq_ref | const,system | null | ALL(所有)
全表扫描,MySQL 从头到尾扫描整张表查找行。
mysql> explain select * from a\G
...
type: ALL
如果加上 limit 如 select * from a limit 100 MySQL 会扫描 100 行,但扫描方式不会变,还是从头到尾扫描。 index(索引)
根据索引来读取数据,如果索引已包含了查询数据,只需扫描索引树,否则执行全表扫描和All类似;
create table a(a_id int not null, key(a_id));
insert into a value(1),(2);
mysql> explain select a_id from a\G
...
type: index range(范围)
以范围的形式扫描索引
建表:
create table a(a_id int not null, key(a_id));
insert into a values(1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
mysql> explain select * from a where a_id > 1\G
...
type: range
... IN 比较符也会用 range 表示:
mysql> explain select * from a where a_id in (1,3,4)\G
...
type: range
... `
ref(引用)
非唯一性索引访问
建表:
create table a(a_id int not null, key(a_id));
insert into a values(1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
mysql> explain select * from a where a_id=1\G
...
type: ref
... eq_ref(等值引用)
使用有唯一性索引查找(主键或唯一性索引)
建表及插入数据:
create table a(id int primary key);
create table a_info(id int primary key, title char(1));
insert into a value(1),(2);
insert into a_info value(1, 'a'),(2, 'b');
mysql> explain select * from a join a_info using(id);
...+--------+--------+...
...| table | type |...
...+--------+--------+...
...| a | index |...
...| a_info | eq_ref |...
...+--------+--------+...
此时 a_info 每条记录与 a 一一对应,通过主键 id 关联起来,所以 a_info 的 type 为 eq_ref。
删除 a_info 的主键:ALTER TABLE `a_info` DROP PRIMARY KEY;
现在 a_info 已经没有索引了:
mysql> explain select * from a join a_info using(id);
+----+...+--------+--------+...
| id |...| table | type |...
+----+...+--------+--------+...
| 1 |...| a_info | ALL |...
| 1 |...| a | eq_ref |...
+----+...+--------+--------+...
这次 MySQL 调整了执行顺序,先全表扫描 a_info 表,再对表 a 进行 eq_ref 查找,因为 a 表 id 还是主键。
删除 a 的主键:alter table a drop primary key;
现在 a 也没有索引了:
mysql> explain select * from a join a_info using(id);
...+--------+------+...
...| table | type |...
...+--------+------+...
...| a | ALL |...
...| a_info | ALL |...
...+--------+------+...
现在两个表都使用全表扫描了。 建表及插入数据:
create table a(id int primary key);
create table a_info(id int, title char(1), key(id));
insert into a value(1),(2);
insert into a_info value(1, 'a'),(2, 'b');
现在 a_info 表 id 列变为普通索引(非唯一性索引):
mysql> explain select * from a join a_info using(id) where a.id=1;
...+--------+-------+...
...| table | type |...
...+--------+-------+...
...| a | const |...
...| a_info | ref |...
...+--------+-------+...
a_info 表 type 变为 ref 类型了。
所以,唯一性索引才会出现 eq_ref (非唯一性索引会出现 ref ),因为唯一,所以最多只返回一条记录,找到后无需继续查找,因此比 ref 更快。 const(常量连接)
被称为“常量”,这个词不好理解,不过出现 const 的话就表示发生下面两种情况:
在整个查询过程中这个表最多只会有一条匹配的行,比如主键 id=1 就肯定只有一行,只需读取一次表数据便能取得所需的结果,且表数据在分解执行计划时读取。返回值直接放在 select 语句中,类似 select 1 AS f 。可以通过 extended 选择查看内部过程: 建表及插入数据:
create table a(id int primary key, c1 char(20) not null, c2 text not null, c3 text not null);
insert into a values(1, 'asdfasdf', 'asdfasdf', 'asdfasdf'), (2, 'asdfasdf', 'asdfasdf', 'asdfasdf');
mysql> explain extended select * from a where id=1\G
...
type: const
possible_keys: PRIMARY
key: PRIMARY
...
用 show warnings 查看 MySQL 是如何优化的:
mysql> show warnings\G
...
Message: select '' AS `id`,'asdfasdf' AS `c1`,'asdfasdf' AS `c2`,'asdfasdf' AS
`c3` from `test`.`a` where 1
查询返回的结果为:
mysql> select * from a where id=1;
+----+----------+----------+----------+
| id | c1 | c2 | c3 |
+----+----------+----------+----------+
| 1 | asdfasdf | asdfasdf | asdfasdf |
+----+----------+----------+----------+
可以看出,返回结果中的字段值都以“值 AS 字段名”的形式直接出现在优化后的 select 语句中。
修改一下查询:
mysql> explain select * from a where id in(1,2)\G
...
type: range
...
当返回结果超过 1 条时, type 便不再为 const 了。
重新建表及插入数据:
create table a (id int not null);
insert into a value(1),(2),(3);
mysql> explain select * from a where id=1\G
...
type: ALL
目前表中只有一条 id=1 的记录,但 type 已为 ALL ,因为只有唯一性索引才能保证表中最多只有一条记录,只有这样 type 才有可能为 const 。
为 id 加普通索引后, type 变为 ref ,改为加唯一或主键索引后, type 便变为 const 了。 二、Extra 列
Extra表示附加信息,常见的有如下几种(也按查询效率从高到低排列):
Using index:表示使用索引,如果只有 Using index,说明他没有查询到数据表,只用索引表就完成了这个查询,这个叫覆盖索引。如果同时出现Using where,代表使用索引来查找读取记录, 也是可以用到索引的,但是需要查询到数据表。
Using where:表示条件查询,如果不读取表的所有数据,或不是仅仅通过索引就可以获取所有需要的数据,则会出现 Using where。如果type列是ALL或index,而没有出现该信息,则你有可能在执行错误的查询:返回所有数据。
Using filesort:不是“使用文件索引”的含义!filesort是MySQL所实现的一种排序策略,通常在使用到排序语句ORDER BY的时候,会出现该信息。
Using temporary:表示为了得到结果,使用了临时表,这通常是出现在多表联合查询,结果排序的场合。 如果EXPLAIN出现后面两个信息(Using filesort,Using temporary),而rows又比较大,通常意味着你需要调整查询语句,或者需要添加索引,总之需要尽量消除这两个信息。 转自:http://blog.csdn.net/xtdhqdhq/article/details/20377273
MySQL之EXPLAIN 执行计划详解的更多相关文章
- MySQL性能分析, mysql explain执行计划详解
MySQL性能分析 MySQL性能分析及explain用法的知识是本文我们主要要介绍的内容,接下来就让我们通过一些实际的例子来介绍这一过程,希望能够对您有所帮助. 1.使用explain语句去查看分析 ...
- MySql——Explain执行计划详解
使用explain关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的,分析你的查询语句或是表结构的性能瓶颈. explain执行计划包含的信息 其中最重要的字段为:i ...
- ( 转 ) MySQL高级 之 explain执行计划详解
使用explain关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的,分析你的查询语句或是表结构的性能瓶颈. explain执行计划包含的信息 其中最重要的字段为:i ...
- MySQL高级 之 explain执行计划详解
使用explain关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的,分析你的查询语句或是表结构的性能瓶颈. explain执行计划包含的信息 其中最重要的字段为:i ...
- MySQL高级 之 explain执行计划详解(转)
使用explain关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的,分析你的查询语句或是表结构的性能瓶颈. explain执行计划包含的信息 其中最重要的字段为:i ...
- Mysql探索之Explain执行计划详解
前言 如何写出效率高的SQL语句,提到这必然离不开Explain执行计划的分析,至于什么是执行计划,如何写出高效率的SQL,本篇文章将会一一介绍. 执行计划 执行计划是数据库根据 SQL 语句和相关表 ...
- 【夯实Mysql基础】mysql explain执行计划详解
原文地址 1).id列数字越大越先执行,如果说数字一样大,那么就从上往下依次执行,id列为null的就表是这是一个结果集,不需要使用它来进行查询. 2).select_type列常见的有: A ...
- mysql explain执行计划详解
1).id列数字越大越先执行,如果说数字一样大,那么就从上往下依次执行,id列为null的就表是这是一个结果集,不需要使用它来进行查询. 2).select_type列常见的有: A:simp ...
- MySQL — 优化之explain执行计划详解(转)
EXPLAIN简介 EXPLAIN 命令是查看查询优化器如何决定执行查询的主要方法,使用EXPLAIN,只需要在查询中的SELECT关键字之前增加EXPLAIN这个词即可,MYSQL会在查询上设置一个 ...
随机推荐
- (Alpha)Let's-技术文档(技术规格说明书)
技术规格说明书 抽象 首先,对抽象原则的理解,“抽象”这一概念本身就很抽象.抽象体现的是一种概括能力.我们生活中遇到的很多客体,其在某些方面具备有一些相似甚至相同的性质,以这些特点而非事物本身来认识鉴 ...
- Beta版本讨论
目录 组员:胡绪佩 组员:何家伟 组员:黄鸿杰 组员: 翟丹丹 组员:周政演 组员:胡青元 组员:庄卉 组员:刘恺琳 组员:何宇恒 组员:刘一好 组员:葛家灿 组员:胡绪佩 总结 通过这次的Beta版 ...
- Win 2008 r2 远程桌面多用户登陆,一用户多登陆配置
Windows 2008 R2远程桌面,设置最大连接数,一个登录后另一个就被踢掉等问题 Windows 2008 R2配置如图: 1.打开远程桌面回话主机配置 2.右键RDP-Tcp,属性,可设置最大 ...
- 利用mask-image蒙层编写异形头像
需求:后台给了一个规规矩矩的头像,或圆或方,UI要求展示成水滴的形状.正在想到底如何实现的时候,不由自主去翻了鑫神的博客,正好找到了答案,窃喜(·_·) UI给的形状: 后台给的头像(忽略橙色背景色, ...
- springmvc下载文件
Controller内代码: @RequestMapping(value = "/upload") public ResponseEntity<byte[]> uplo ...
- mysql 好用的sql语句
1.删除某个库里面全部的表 ,先在mysql库中执行: SELECT CONCAT('drop table ',table_name,';') FROM information_schema.`TA ...
- 实体框架自定义代码优先约定(EF6以后)
仅限EF6仅向前 - 此页面中讨论的功能,API等在实体框架6中引入.如果您使用的是早期版本,则部分或全部信息不适用. 使用Code First时,您的模型是使用一组约定从您的类计算的.默认的Code ...
- C++11 自动推导auto
C++11 自动推导auto C++11中引入的auto主要有两种用途:自动类型推导和返回值占位. auto在C++98中的标识临时变量的语义,由于使用极少且多余,在C++11中已被删除.前后两个标准 ...
- MT【105】待定系数算最大最小
已知$x,y,z>0$,则$max\{2x,\frac{1}{y},y+\frac{1}{x}\}$的最小值______ 分析:首先关注到$2x=\frac{1}{y}=y+\frac{1}{x ...
- 什么是Flume
1.什么是Flume FLUME 是HADOOP生态圈中的一个组件.主要应用于实时数据的流处理,比如一旦有某事件触发(如本地交易引起的数据改动)可以将实时的日志数据发向HADOOP文件系统HDFS中 ...