mysql select type_Mysql Explain之type详解

select version():5.7.21

EXPLAIN 是什么

MySQL 提供了一个 EXPLAIN 命令, 它可以对 SQL 语句进行分析, 并输出 SQL 执行的详细信息, 以供开发人员针对性优化.

例如分析一条 SELECT 语句

EXPLAIN SELECT * FROM `user` WHERE id = 1

复制代码

8b604fa0b290fc53acacf21fb0aca0e5.png

EXPLAIN 结果中的type字段

Tips:常见的扫描方式

system:系统表,少量数据,往往不需要进行磁盘IO

const:常量连接

eq_ref:主键索引(primary key)或者非空唯一索引(unique not null)等值扫描

ref:非主键非唯一索引等值扫描

range:范围扫描

index:索引树扫描

ALL:全表扫描(full table scan)

type扫描方式由快到慢

system > const > eq_ref > ref > range > index > ALL

复制代码

1.system

4fffca9ea9a62b8b5dd41fe1eb2e3034.png

上例中,从系统库mysql的系统标proxies_priv里查询数据,这里的数据在Mysql服务启动时候已经加载在内存中,不需要进行磁盘IO。

官方文档中的解释:该表只有一行(=系统表)。这是const联接类型的特例

2.const

模拟数据

create table user (

id int primary key,

name varchar(20)

)engine=innodb;

insert into user values(1,'ar414');

insert into user values(2,'zhangsan');

insert into user values(3,'lisi');

insert into user values(4,'wangwu');

复制代码

Explain分析结果

bb8a3011e91ce6a095850c6d570cd2a0.png

上例中id是主键(primary key),连接部分是常量1,通过索引一次就能找到,速度非常快

场景:

命中主键(primary key)或者唯一索引(unique)

被连接的部分是一个常量值(const)

3.eq_ref

模拟数据

create table user (

id int primary key,

name varchar(20)

)engine=innodb;

insert into user values(1,'ar414');

insert into user values(2,'zhangsan');

insert into user values(3,'lisi');

insert into user values(4,'wangwu');

create table user_balance (

uid int primary key,

balance int

)engine=innodb;

insert into user_balance values(1,100);

insert into user_balance values(2,200);

insert into user_balance values(3,300);

insert into user_balance values(4,400);

insert into user_balance values(5,500);

复制代码

Explain分析结果

33ba8944a6e2d298fd4f34f8dbc45919.png

上例中对于前表user表中的每一行(row),对应后user_balance表只有一行被扫描,这类扫描的速度也非常的快

场景:

联表(join)查询

命中主键(primary key)或者非空唯一索引(unique not null)

等值连接

4.ref

模拟数据

同eq_ref模拟数据区别:user_balance表中的主键索引改为普通索引

create table user (

id int primary key,

name varchar(20)

)engine=innodb;

insert into user values(1,'ar414');

insert into user values(2,'zhangsan');

insert into user values(3,'lisi');

insert into user values(4,'wangwu');

create table user_balance (

uid int,

balance int,

index(uid)

)engine=innodb;

insert into user_balance values(1,100);

insert into user_balance values(2,200);

insert into user_balance values(3,300);

insert into user_balance values(4,400);

insert into user_balance values(5,500);

复制代码

Explain分析结果

联表查询

f95c5a40368c22877eb6e0cf4b819607.png

由于后表使用了普通非唯一索引,对于前表user表的每一行(row),后表user_balance表可能有多于一行的数据被扫描

单表查询

2d8a2fbf0175b58f3474e10066f9e740.png

当id改为普通非唯一索引后,常量的连接查询,也由const降级为了ref,因为非唯一索引所以有多于一行的数据被可能被扫描

ref每一次匹配可能有多行数据返回,虽然它比eq_ref要慢,但它仍然是一个很快的join类型

场景:

联表查询

普通非唯一索引

5.range

模拟数据

create table user (

id int primary key,

name varchar(20)

)engine=innodb;

insert into user values(1,'ar414');

insert into user values(2,'zhangsan');

insert into user values(3,'lisi');

insert into user values(4,'wangwu');

insert into user values(5,'zhaoliu');

复制代码

Explain分析结果

between

0b46785ac4f2102661b1df53670ee067.png

in

a03d72aa47d8c023fcad557104bb04f9.png

>,>=,

de3a8e1211b8d2922a710564c95435da.png

range比较好理解,它是索引上的范围查询,它会在索引上扫码特定范围内的值

6.index

话外音:当前测试表为InnoDb,MyISAM 内置了一个计数器,count()时它直接从计数器中读

1cc2effeb97cd0314ff56ad51ba78a9b.png

index类型,需要扫描索引上的全部数据,它仅比全表扫描快一点

7.ALL

模拟数据

create table user (

id int,

name varchar(20)

)engine=innodb;

insert into user values(1,'ar414');

insert into user values(2,'zhangsan');

insert into user values(3,'lisi');

insert into user values(4,'wangwu');

insert into user values(5,'zhaoliu');

复制代码

Explain分析结果

48d7e416a0d153e31e75e70ea6f1ff02.png

如果id上不建索引,则全表扫描

总结

type类型从快到慢:system>const>eq_ref>ref>range>index>ALL

作为一名合格的后端开发者应该熟悉掌握Explain

结合业务建立正确索引,而不是每个字段建立索引(滥用)

b739ec46bb5c46d9c0aa4ce35ba1ea56.png

关于找一找教程网

本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。

本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。

[Mysql Explain之type详解]http://www.zyiz.net/tech/detail-133395.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值