前言
在MySQL中,我们可以通过EXPLAIN命令获取MySQL如何执行SELECT语句的信息,包括在SELECT语句执行过程中表如何连接和连接的顺序。
下面分别对EXPLAIN命令结果的每一列进行说明:
.select_type:表示SELECT的类型,常见的取值有:
类型
说明
SIMPLE
简单表,不使用表连接或子查询
PRIMARY
主查询,即外层的查询
UNION
UNION中的第二个或者后面的查询语句
SUBQUERY
子查询中的第一个
.table:输出结果集的表(表别名)
.type:表示MySQL在表中找到所需行的方式,或者叫访问类型。常见访问类型如下,从上到下,性能由差到最好:
ALL
全表扫描
index
索引全扫描
range
索引范围扫描
ref
非唯一索引扫描
eq_ref
唯一索引扫描
const,system
单表最多有一个匹配行
NULL
不用扫描表或索引
1、type=ALL,全表扫描,MySQL遍历全表来找到匹配行
一般是没有where条件或者where条件没有使用索引的查询语句
EXPLAIN SELECT * FROM customer WHERE active=0;
2、type=index,索引全扫描,MySQL遍历整个索引来查询匹配行,并不会扫描表
一般是查询的字段都有索引的查询语句
EXPLAIN SELECT store_id FROM customer;
3、type=range,索引范围扫描,常用于<、<=、>、>=、between等操作
EXPLAIN SELECT * FROM customer WHERE customer_id>=10 AND customer_id<=20;
注意这种情况下比较的字段是需要加索引的,如果没有索引,则MySQL会进行全表扫描,如下面这种情况,create_date字段没有加索引:
EXPLAIN SELECT * FROM customer WHERE create_date>='2006-02-13' ;
4、type=ref,使用非唯一索引或唯一索引的前缀扫描,返回匹配某个单独值的记录行
store_id
字段存在普通索引(非唯一索引)
EXPLAIN SELECT * FROM customer WHERE store_id=10;
ref类型还经常会出现在join操作中:
customer、payment表关联查询,关联字段customer.customer_id
(主键),payment.customer_id
(非唯一索引)。表关联查询时必定会有一张表进行全表扫描,此表一定是几张表中记录行数最少的表,然后再通过非唯一索引寻找其他关联表中的匹配行,以此达到表关联时扫描行数最少。
因为customer、payment两表中customer表的记录行数最少,所以customer表进行全表扫描,payment表通过非唯一索引寻找匹配行。
EXPLAIN SELECT * FROM customer customer INNER JOIN payment payment ON customer.customer_id = payment.customer_id;
5、type=eq_ref,类似ref,区别在于使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配
eq_ref一般出现在多表连接时使用primary key或者unique index作为关联条件。
film、film_text表关联查询和上一条所说的基本一致,只不过关联条件由非唯一索引变成了主键。
EXPLAIN SELECT * FROM film film INNER JOIN film_text film_text ON film.film_id = film_text.film_id;
6、type=const/system,单表中最多有一条匹配行,查询起来非常迅速,所以这个匹配行的其他列的值可以被优化器在当前查询中当作常量来处理
const/system出现在根据主键primary key或者 唯一索引 unique index 进行的查询
根据主键primary key进行的查询:
EXPLAIN SELECT * FROM customer WHERE customer_id =10;
根据唯一索引unique index进行的查询:
EXPLAIN SELECT * FROM customer WHERE email ='MARY.SMITH@sakilacustomer.org';
7、type=NULL,MySQL不用访问表或者索引,直接就能够得到结果
.possible_keys: 表示查询可能使用的索引
.key: 实际使用的索引
.key_len: 使用索引字段的长度
.ref: 使用哪个列或常数与key一起从表中选择行。
.rows: 扫描行的数量
.filtered: 存储引擎返回的数据在server层过滤后,剩下多少满足查询的记录数量的比例(百分比)
.Extra: 执行情况的说明和描述,包含不适合在其他列中显示但是对执行计划非常重要的额外信息
最主要的有一下三种:
Using Index
表示索引覆盖,不会回表查询
Using Where
表示进行了回表查询
Using Index Condition
表示进行了ICP优化
Using Flesort
表示MySQL需额外排序操作, 不能通过索引顺序达到排序效果
什么是ICP?
MySQL5.6引入了Index Condition Pushdown(ICP)的特性,进一步优化了查询。Pushdown表示操作下放,某些情况下的条件过滤操作下放到存储引擎。
EXPLAIN SELECT * FROM rental WHERE rental_date='2005-05-25' AND customer_id>=300 AND customer_id<=400;
在5.6版本之前:
优化器首先使用复合索引idx_rental_date过滤出符合条件rental_date='2005-05-25'
的记录,然后根据复合索引idx_rental_date回表获取记录,最终根据条件customer_id>=300 AND customer_id<=400
过滤出最后的查询结果(在服务层完成)。
在5.6版本之后:
MySQL使用了ICP来进一步优化查询,在检索的时候,把条件customer_id>=300 AND customer_id<=400
也推到存储引擎层完成过滤,这样能够降低不必要的IO访问。Extra为Using index condition
就表示使用了ICP优化。
参考
《深入浅出MySQL》
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新动态
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]