在以前的面试过程当中,问到执行计划,有不少童鞋不知道是什么?甚至将执行计划与执行时间认为是同一个概念。今天咱们就一块儿来了解一下执行计划究竟是什么?有什么用途?面试
执行计划,简单的来讲,是SQL在数据库中执行时的表现状况,一般用于SQL性能分析,优化等场景。在MySQL使用 explain 关键字来查看SQL的执行计划。以下所示:数据库
1.查询t_base_user
select * from t_base_user where name="andyqian";微信
2.查看上述语句的执行计划
explain select * from t_base_user where name="andyqian";数据结构
执行查看上述2语句后,咱们能够得出如下执行计划结果性能
id | select_type | table | type | possible_kes | key | key_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | t_base_user | ALL | 1 | Using where |
上面执行计划是什么意思呢?有什么参考价值呢?大数据
上面这个执行计划给到的信息是: 这个结果经过一个简单的语句全表扫描,共扫描1行,使用where条件在t_base_user表中筛选出的。发现该语句并无走索引,为何是这样的呢?别急,咱们紧接着看下一节。优化
经过上面,咱们知道了什么是执行计划,也看到了执行计划究竟是什么东西,如今咱们来具体了解一下,MySQL执行计划中,每一个属性表明的是什么意思?spa
id | select_type | table | type | possible_kes | key | key_len | ref | rows | Extra |
---|
咱们一一来介绍,并说明每一个属性有哪些可选值,以及每一个可选值的意思。.net
id
表示查询中select操做表的顺序,按顺序从大到依次执行设计
select_type :
该表示选择的类型,可选值有: SIMPLE(简单的),
type :
该属性表示访问类型,有不少种访问类型。
最多见的其中包括如下几种: ALL(全表扫描), index(索引扫描),range(范围扫描),ref (非惟一索引扫描),eq_ref(惟一索引扫描,),(const)常数引用, 访问速度依次由慢到快。
其中 : range(范围)常见与 between and ..., 大于 and 小于这种状况。
提示 : 慢SQL是否走索引,走了什么索引,也就能够经过该属性查看了。
table :
表示该语句查询的表
possible_keys :
顾名思义,该属性给出了,该查询语句,可能走的索引,(如某些字段上索引的名字)这里提供的只是参考,而不是实际走的索引,也就致使会有possible_Keys不为null,key为空的现象。
key : 显示MySQL实际使用的索引,其中就包括主键索引(PRIMARY),或者自建索引的名字。
key_len : 表示索引所使用的字节数,
ref :
链接匹配条件,若是走主键索引的话,该值为: const, 全表扫描的话,为null值
rows :
扫描行数,也就是说,须要扫描多少行,采能获取目标行数,通常状况下会大于返回行数。一般状况下,rows越小,效率越高, 也就有大部分SQL优化,都是在减小这个值的大小。
注意: 理想状况下扫描的行数与实际返回行数理论上是一致的,但这种状况及其少,如关联查询,扫描的行数就会比返回行数大大增长)
Extra 这个属性很是重要,该属性中包括执行SQL时的真实状况信息,如上面所属,使用到的是"using where",表示使用where筛选获得的值,经常使用的有: "Using temporary": 使用临时表 "using filesort": 使用文件排序
看到这里,咱们应该已经发现,在第一步中,咱们的这条SQL
select * from t_base_user where name="andyqian";
是没有走索引的,并且仍是全表扫描,在数据量少的状况下,问题还不会特别突出,若是数据量比较大,这但是个会形成生产事故的慢查询哦,如今咱们改造一下,将name字段添加上索引,
添加索引
alter table t_base_user add index idx_name(name);
看看它的执行计划是怎样的。
id | select_type | table | type | possible_kes | key | key_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | t_base_user | ref | idx_name | idx_name | 93 | cons | 1 | Using where |
你看,如今已经走idx_name索引了,其type从All(全表扫描)到ref(非惟一索引了),别看就只有这一点点小区别,在大数据量的时候,但是会起大做用的哦。
本文中演示的数据结构以下:
create table t_base_user(
oid bigint(20) not null primary key auto_increment,
name varchar(30) null comment "name",
email varchar(30) null comment "email",
age int null comment "age",
telephone varchar(30) null comment "telephone",
status tinyint(4) null comment "0 无效 1 有效",
created_at datetime null comment "",
updated_at datetime null comment ""
)
// 新增记录:
insert into t_base_user (name,email,age,telephone,created_at,updated_at) values ("andyqian","andytohome",20,"15608411",now(),now();)
一个好的数据库表设计,从一开始就应该考虑添加索引,而不是到最后发现慢SQL了,影响业务了,才来补救。其实我在工做经历当中,因为新建表,或新加字段后,忘记添加索引也形成了屡次生产事故,记忆犹新!!! 其实新建索引也是有必定的原则的,建什么索引,建在哪些字段上,这里面还有很多知识呢,下一篇文章写,尽请期待吧!
扫码关注,一块儿进步
我的博客: http://www.andyqian.com