学会使用`EXPLAIN`语句

引言

平常工做中,使用MySQL的机会仍是蛮多的,主要考虑Schema与数据类型优化如何建立索引根据业务场景的查询优化。这些想必你们都在高性能MySQL这本书中看过,可能也比做者理解的深,本文旨在对EXPLAIN语句使用、分析进行整理。html

EXPLAIN语句是什么?

官网对于EXPLAIN的做用定义以下:mysql

The EXPLAIN statement provides information about how MySQL executes statements. EXPLAIN works with SELECT, DELETE, INSERT, REPLACE, and UPDATE statements.sql

简单来说,EXPLAIN语句告诉咱们MySQL如何执行SQL语句,而咱们经过这些信息,能够达到优化SQL语句执行效率的目的。数据库

接下来,就要对EXPLAIN返回的格式进行了解了,具体以下:ide

字段名 字段描述
id 查询语句内SELECT的序列号
select_type SELECT类型
table 访问的表名
partitions 命中分区
type 数据访问类型,下文详细介绍
possible_keys 有关索引,实际状况可能不可用
key MySQL查询优化器实际使用的索引
key_len 索引存储长度
ref 实际使用的索引中,用于比较的常量或列
rows 查询须要读取的行数,innodb引擎是一个衡量效率的指标,有时可能不许确
Extra 查询执行的附加信息,下文详细介绍
  • 在分析SQL语句执行时,主要用到的列,分别为typeExtra,下文的测试用例均为官网提供的sakila数据库,附上下载连接性能

  • 本文使用MySQL 8.0.十二、Navicat 12.1测试

type列主要出现值(性能从好到差)

  • system:表只有一行,const类型的特殊状况。
  • const:查询结果最多有一行,多为主键惟一索引与常量比较的状况。
explain select * from actor where actor_id = 1
复制代码
  • eq_ref:一种特殊的索引查找,MySQL知道最多只返回一条符合条件的记录,使用主键NOT NULL的惟一索引会看到(用navicat发现结果也是ref)。
explain select * from actor, film_actor where actor.actor_id = film_actor.actor_id and actor.actor_id = 1
复制代码
  • ref:一种索引查找,返回全部匹配某个单个值的行,然而,可能会找到多个符合条件的行,当使用非惟一性索引或者惟一性索引的非惟一性前缀时发生。
explain select * from film where title= 'ACE GOLDFINGER'
复制代码
  • range:范围扫描就是一个有限制的索引扫描, 不用遍历全部索引,例如索引在BETWEEN>>范围内的。
explain select * from film where film_id BETWEEN 1 AND 100
复制代码
  • index:全表扫描,只是MySQL扫描表时按索引次序而不是行。

Extra列中看到“Using index”,说明是覆盖索引,只须要读取索引列,不须要读取行数据。 使用索引次序全表读取。优化

explain select actor.actor_id from film_actor, actor where film_actor.actor_id = actor.actor_id 
复制代码
  • ALL:全表扫描,读取行数据,找到须要的行。
explain select * from film_actor, actor where film_actor.actor_id = actor.actor_id 
复制代码

Extra列主要出现的值

  • Using index:使用覆盖索引,避免回表查询行数据。
  • Using where:存储引擎检索行后再进行过滤。
  • Using temporary:对查询结果排序时会使用一个临时表,尽可能避免使用临时表
  • Using filesort:对结果使用一个外部索引排序,而不是按索引次序从表里读取行,须要进行优化

总结

因为查询优化器的存在,实际运行查询语句会和想的不一致,所以在进行查询语句优化时,最好运行下EXPLAIN语句,看看是否是和本身想的一致。spa

参考文献

相关文章
相关标签/搜索