在之前的面试过程中,问到执行计划,有很多童鞋不知道是什么?甚至将执行计划与执行时间认为是同一个概念。今天我们就一起来了解一下执行计划到底是什么?有什么用途
执行计划,简单的来说,是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";
1 2 3 4 5 |
//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执行计划中,每个属性代表的是什么意思
id | select_type | table | type | possible_kes | key | key_len | ref | rows | Extra |
---|
我们一一来介绍,并说明每个属性有哪些可选值,以及每个可选值的意思。
看到这里,我们应该已经发现,在第一步中,我们的这条SQL
- select * from t_base_user where name="andyqian";
1 |
select * from t_base_user where name="andyqian"; |
是没有走索引的,而且还是全表扫描,在数据量少的情况下,问题还不会特别突出,如果数据量比较大,这可是个会造成生产事故的慢查询哦,现在我们改造一下,将name字段添加上索引,
- # 添加索引
- alter table t_base_user add index idx_name(name);
1 2 |
# 添加索引 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@gmail.com",20,"15608411",now(),now());
- )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# 创建表 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@gmail.com",20,"15608411",now(),now()); ) |
一个好的数据库表设计,从一开始就应该考虑添加索引,而不是到最后发现慢SQL了,影响业务了,才来补救。其实我在工作经历当中,由于新建表,或新加字段后,忘记添加索引也造成了多次生产事故,记忆犹新!!!
其实新建索引也是有一定的原则的,建什么索引,建在哪些字段上,这里面还有不少知识呢,下一篇文章写,尽请期待吧!
来源: http://blog.jobbole.com/112877/