mysql explain用法

explain显示了mysql如何使用索引来处理select语句以及连接表。可以帮助选择更好的索引和写出更优化的查询语句。
使用方法,在select语句前加上explain就可以了,如:

explain select * from statuses_status where id=11;

创建测试表:

复制代码
CREATE TABLE people(id int auto_increment primary key, zipcode char(32) not null default '', address varchar(128) not null default '', lastname char(64) not null default '', firstname char(64) not null default '', birthdate char(10) not null default '' ); CREATE TABLE people_car( people_id int, plate_number varchar(16) not null default '', engine_number varchar(16) not null default '', lasttime timestamp );
复制代码

 插入测试数据:

复制代码
insert into people
(zipcode,address,lastname,firstname,birthdate)
values
('230031','anhui','zhan','jindong','1989-09-15'), ('100000','beijing','zhang','san','1987-03-11'), ('200000','shanghai','wang','wu','1988-08-25') insert into people_car (people_id,plate_number,engine_number,lasttime) values (1,'A121311','12121313','2013-11-23 :21:12:21'), (2,'B121311','1S121313','2011-11-23 :21:12:21'), (3,'C121311','1211SAS1','2012-11-23 :21:12:21')
复制代码

 创建索引用来测试

alter table people add index(zipcode,firstname,lastname);

 explain介绍

先从一个最简单的查询开始:

Query-1
explain select zipcode,firstname,lastname from people;

 explain输出结果共有id,select_type,table,type,possible_keys,key,key_len,ref,rows和Extra几列。每一列分别代表什么意思呢,请看下面的解释。

select_type 表示查询中每个select语句的类型(简单 OR复杂),可以有下面几种

a.SIMPLE:最简单的SELECT查询,没有使用UNION或子查询,见Query-1。

b.PRIMARY:在嵌套的查询中是最外层的SELECT语句,在UNION查询中是最前面的SELECT语句。见Query-2和Query-3。

                    查询中若包含任何复杂的子部分,最外层查询则被标记为:PRIMARY

Query-2
explain select zipcode from (select * from people a) b;

Query-3
explain select * from people where zipcode = 100000 union select * from people where zipcode = 200000;

c.UNION:UNION中第二个以及后面的SELECT语句。见Query-3。

d.DERIVED:派生表SELECT语句中FROM子句中的SELECT语句。见Query-2。

e.UNION RESULT:一个UNION查询的结果。见Query-3。

f.DEPENDENT UNION:顾名思义,首先需要满足UNION的条件,及UNION中第二个以及后面的SELECT语句,同时该语句依赖外部的查询。

Query-4
explain select * from people where id in (select id from people where zipcode = 100000 union select id from people where zipcode = 200000 );

g.SUBQUERY:子查询中第一个SELECT语句。

Query-6
explain select * from people where id = (select id from people where zipcode = 100000);

table :显示的这一行信息是关于哪一张表的。有时候并不是真正的表名。

Query-7
explain select * from (select * from (select * from people a) b ) c;

可以看到如果指定了别名就显示的别名。
<derivedN>N就是id值,指该id值对应的那一步操作的结果。
还有<unionM,N>这种类型,出现在UNION语句中,见Query-4。
注意:MySQL对待这些表和普通表一样,但是这些“临时表”是没有任何索引的。

type
type列很重要,是用来说明表与表之间是如何进行关联操作的,有没有使用索引。MySQL中“关联”一词比一般意义上的要宽泛,MySQL认为任何一次查询都是一次“关联”,并不仅仅是一个查询需要两张表才叫关联,所以也可以理解MySQL是如何访问表的。主要有下面几种类别。

const

当确定最多只会有一行匹配的时候,MySQL优化器会在查询前读取它而且只读取一次,因此非常快。const只会用在将常量和主键或唯一索引进行比较时,而且是比较所有的索引字段。people表在id上有一个主键索引,在(zipcode,firstname,lastname)有一个二级索引。因此Query-8的type是const而Query-9并不是:

Query-8
explain select * from people where id=1;

Query-9
explain select * from people where zipcode = 100000;

注意下面的Query-10也不能使用const table,虽然也是主键,也只会返回一条结果。

Query-10
explain select * from people where id >2;

system
这是const连接类型的一种特例,表仅有一行满足条件。

Query-11
explain select * from (select * from people where id = 1 )b;

<derived2>已经是一个const table并且只有一条记录。

eq_ref

唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。 常见于主键或唯一索引扫描。eq_ref类型是除了const外最好的连接类型。
创建员工表Employee和经理表Manager

复制代码
create table Employee
(ID int auto_increment,Ename varchar(32), Age int, Salary float, MID int, Primary key (ID) ); create table Manager ( MID int, Name varchar(32), Primary key(MID) );
复制代码
Query-12
explain select * from Employee A,Manager B where A.MID=B.MID;

MID对于表Manager是唯一的,主键索引,来与employee连接,故type为eq_ref。

ref

非唯一性索引扫描,返回匹配某个单独值的所有行。常见于使用非唯一索引即唯一索引的非唯一前缀进行的查找。
这个类型跟eq_ref不同的是,它用在关联操作只使用了索引的最左前缀,或者索引不是UNIQUE和PRIMARY KEY。ref可以用于使用=或<=>操作符的带索引的列。

Query-13
explain select * from people where zipcode='100000';

 

zipcode、firstname和lastname组成索引,这里只使用了name,即只使用了唯一性索引的一部分,故为ref。

fulltext
链接是使用全文索引进行的。一般我们用到的索引都是B树,这里就不举例说明了。
ref_or_null
该类型和ref类似。但是MySQL会做一个额外的搜索包含NULL列的操作。在解决子查询中经常使用该联接类型的优化。

range

只检索给定范围的行,使用一个索引来选择行。key列显示使用了哪个索引。key_len包含所使用索引的最长关键元素。在该类型中ref列为NULL。当使用=、<>、>、>=、<、<=、IS NULL、<=>、BETWEEN或者IN操作符,用常量比较关键字列时,可以使用range。

索引范围扫描,对索引的扫描开始于某一点,返回匹配值域的行, 常见于between、<、>,IN等的查询。

Query-14
explain select * from people where id=1 or id=2;

Query-15
explain select * from people where id>1;

Query-16
explain select * from people where id in (1,2);

index
该联接类型与ALL相同,除了只有索引树被扫描。这通常比ALL快,因为索引文件通常比数据文件小。这个类型通常的作用是告诉我们查询是否使用索引进行排序操作。

按索引扫描表,虽然还是全表扫描,但优点是索引是有序的。index与ALL区别为index类型只遍历索引树。

Query-17
explain select * from people order by id;

ALL
最慢的一种方式,即全表扫描。

总结

explain的type列从最差到最好依次是:
ALL:全表扫描。
index:索引扫描。 
range:索引范围扫描。
ref :非唯一性索引扫描。 
eq_ref :唯一性索引扫描。 
const,system:将查询转换为一个常量。 
null:MySQL在优化过程中分解语句,执行时甚至不用访问表或索引

possible_keys
possible_keys列指出MySQL能使用哪个索引在该表中找到行。查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用。

key
key列显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。

key_len
key_len列显示MySQL决定使用的键长度。如果键是NULL,则长度为NULL。使用的索引的长度。在不损失精确性的情况下,长度越短越好 。

ref
ref列显示使用哪个列或常数与key一起从表中选择行。
表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值。

rows
rows列显示MySQL认为它执行查询时必须检查的行数。注意这是一个预估值。

Extra
Extra是EXPLAIN输出中另外一个很重要的列,该列显示MySQL在查询过程中的一些详细信息,包含的信息很多,只选择几个重点的介绍下。

Using filesort 
MySQL有两种方式可以生成有序的结果,通过排序操作或者使用索引,当Extra中出现了Using filesort 说明MySQL使用了后者,但注意虽然叫filesort但并不是说明就是用了文件来进行排序,只要可能排序都是在内存里完成的。大部分情况下利用索引排序更快,所以一般这时也要考虑优化查询了。

Using temporary
说明使用了临时表,一般看到它说明查询需要优化了,就算避免不了临时表的使用也要尽量避免硬盘临时表的使用。

Not exists
MYSQL优化了LEFT JOIN,一旦它找到了匹配LEFT JOIN标准的行, 就不再搜索了。

Using index 
说明查询是覆盖了索引的,这是好事情。MySQL直接从索引中过滤不需要的记录并返回命中的结果。这是MySQL服务层完成的,但无需再回表查询记录。

Using index condition
这是MySQL 5.6出来的新特性,叫做“索引条件推送”。简单说一点就是MySQL原来在索引上是不能执行如like这样的操作的,但是现在可以了,这样减少了不必要的IO操作,但是只能用在二级索引上。

Using where
使用了WHERE从句来限制哪些行将与下一张表匹配或者是返回给用户。

注意:Extra列出现Using where表示MySQL服务器将存储引擎返回服务层以后再应用WHERE条件过滤。


转自:http://www.cnblogs.com/xiaoxi/p/5688096.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/443314.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux 性能检查命令总结

如果你的Linux服务器突然负载暴增&#xff0c;告警短信快发爆你的手机&#xff0c;如何在最短时间内找出Linux性能问题所在&#xff1f;

线程池的各种使用场景

&#xff08;1&#xff09;高并发、任务执行时间短的业务&#xff0c;线程池线程数可以设置为CPU核数1&#xff0c;减少线程上下文的切换 &#xff08;2&#xff09;并发不高、任务执行时间长的业务要区分开看&#xff1a; a&#xff09;假如是业务时间长集中在IO操作上…

Java线程面试题 Top 50

不管你是新程序员还是老手&#xff0c;你一定在面试中遇到过有关线程的问题。Java语言一个重要的特点就是内置了对并发的支持&#xff0c;让Java大受企业和程序员的欢迎。大多数待遇丰厚的Java开发职位都要求开发者精通多线程技术并且有丰富的Java程序开发、调试、优化经验&…

深入理解Semaphore

使用 Semaphore是计数信号量。Semaphore管理一系列许可证。每个acquire方法阻塞&#xff0c;直到有一个许可证可以获得然后拿走一个许可证&#xff1b;每个release方法增加一个许可证&#xff0c;这可能会释放一个阻塞的acquire方法。然而&#xff0c;其实并没有实际的许可证这…

【算法系列之四】柱状图储水

题目&#xff1a; 给定一个数组&#xff0c;每个位置的值代表一个高度&#xff0c;那么整个数组可以看做是一个直方图&#xff0c; 如果把这个直方图当作容器的话&#xff0c;求这个容器能装多少水 例如&#xff1a;3&#xff0c;1&#xff0c;2&#xff0c;4 代表第一个位…

盐城大数据产业园人才公寓_岳西大数据产业园规划设计暨建筑设计方案公布,抢先一睹效果图...

近日&#xff0c;岳西县大数据产业园规划设计暨建筑设计方案公布。岳西县大数据产业园项目总占地面积17014.10㎡(约合25.52亩)&#xff0c;拟建总建筑面积约为61590.84㎡(地上建筑面积39907.49㎡&#xff0c;地下建筑面积21602.35㎡)。以“科技圆环”为主题&#xff0c;组建出一…

【算法系列之五】对称二叉树

给定一个二叉树&#xff0c;检查它是否是镜像对称的。 例如&#xff0c;二叉树 [1,2,2,3,4,4,3] 是对称的。 1/ \2 2/ \ / \ 3 4 4 3但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的: 1/ \2 2\ \3 3 说明: 如果你可以运用递归和迭代两种方法解决这个问题&a…

【算法系列之六】两整数之和

不使用运算符 和 - &#xff0c;计算两整数 a 、b 之和。 示例 1: 输入: a 1, b 2 输出: 3示例 2: 输入: a -2, b 3 输出: 1 方法一&#xff1a;递归 public static int getSum1(int a, int b) {if ((a & b) ! 0) { // 判断是否有进位return getSum1(a ^ b, (a &…

cuda默认函数与c++冲突_好程序员Python教程系列-第8讲:函数和模块

好程序员Python教程系列-第8讲&#xff1a;函数和模块&#xff0c;在讲解本章节的内容之前&#xff0c;我们先来研究一道数学题&#xff0c;请说出下面的方程有多少组正整数解。事实上&#xff0c;上面的问题等同于将8个苹果分成四组每组至少一个苹果有多少种方案&#xff0c;所…

【算法系列之七】合并两个有序链表

将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例&#xff1a; 输入&#xff1a;1->2->4, 1->3->4 输出&#xff1a;1->1->2->3->4->4/*** Definition for singly-linked list.* public cla…

mfc让图片与按钮一起_对许多张图片进行批量裁剪,看看我是如何快速做到的

概要&#xff1a;当我们需要对很多图片进行批量裁剪时&#xff0c;以往的办法是自己一张一张图片去操作&#xff0c;非常麻烦。有没有这样一个工具&#xff0c;能够帮我们批量进行处理呢&#xff1f;之前小编在网上找了非常多的软件&#xff0c;一个一个地安装试用&#xff0c;…

【算法系列之八】删除链表的倒数第N个节点

给定一个链表&#xff0c;删除链表的倒数第 n 个节点&#xff0c;并且返回链表的头结点。 示例&#xff1a; 给定一个链表: 1->2->3->4->5, 和 n 2.当删除了倒数第二个节点后&#xff0c;链表变为 1->2->3->5.说明&#xff1a; 给定的 n 保证是有效的…

手写分页sql_分页查询SQL语句

表结构&#xff1a;DROP TABLE IF EXISTS zhoufoxcn.userlist;CREATE TABLE zhoufoxcn.userlist (UserId int(10) unsigned NOT NULL auto_increment,UserName varchar(45) NOT NULL,Age int(10) unsigned NOT NULL default 10,Sex tinyint(3) unsigned NOT NULL default 1,Ta…

【算法系列之九】合并两个有序数组

给定两个有序整数数组 nums1 和 nums2&#xff0c;将 nums2 合并到 nums1 中&#xff0c;使得 num1 成为一个有序数组。 说明: 初始化 nums1 和 nums2 的元素数量分别为 m 和 n。你可以假设 nums1 有足够的空间&#xff08;空间大小大于或等于 m n&#xff09;来保存 nums2 …

把网卡指定给vm虚拟机_为VMWare虚拟网卡指定静态的MAC地址

当你把虚拟机移到另一台主机或在同一台主机但不同的路径时&#xff0c;虚拟机的MAC地址将会更改。默认情况下VMWare会保证MAC地址的唯一性却不保存固定性&#xff0c;在每次开启虚拟机里的系统时都可能重新分配MAC地址来保证唯一性&#xff0c;若你想保证即使虚拟机被移动后&am…

【算法系列之十】三数之和

给定一个包含 n 个整数的数组 nums&#xff0c;判断 nums 中是否存在三个元素 a&#xff0c;b&#xff0c;c &#xff0c;使得 a b c 0 &#xff1f;找出所有满足条件且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的三元组。 例如, 给定数组 nums [-1, 0, 1,…

android 动态获取全县_省市县 ------ 三级滚动(android)

预先加载仿滚轮实现的全部数据mCityPickerView.init(this);③ 点击响应&#xff1a;ss.setOnClickListener(new View.OnClickListener() {Overridepublic void onClick(View v) {CityConfig cityConfig new CityConfig.Builder().title("选择城市")//标题.build();m…

发电厂电气部分第三版pdf_火力发电厂电气主接线的特点

根据火力发电厂的容量及其在电力系统中的地位&#xff0c;一般可将火力发电厂分为区域性火力发电厂和地方性火力发电厂。这两类火力发电厂的电气主接线有各自的特点。一、区域性火力发电厂的电气主接线1、单机容量及总装机容量都较大单机容量多为300MW、600MW和少量1000MW,电厂…

【算法系列之十一】k个一组翻转链表

给出一个链表&#xff0c;每 k 个节点一组进行翻转&#xff0c;并返回翻转后的链表。 k 是一个正整数&#xff0c;它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍&#xff0c;那么将最后剩余节点保持原有顺序。 示例 : 给定这个链表&#xff1a;1->2->3-&g…

ghostblog主题_读Ghost博客源码与自定义Ghost博客主题

我使用的Ghost博客一直使用者默认的Casper主题。我向来没怎么打理过自己博客&#xff0c;一方面认为自己不够专业&#xff0c;很难写出质量比较高的文字&#xff1b;另一方面认为博客太耗时间&#xff0c;很容易影响正常的工作内容。最近公司即将搬迁&#xff0c;我的开发工作也…