执行计划: 简单的理解就是能够更清楚SQL语句的执行过程。(这个是我个人的理解。如果有误欢迎指出。)
本篇文章将简单讲解MySQL 执行计划,如果想深入了解,请查阅《高性能MySQL》这本书。不是打广告哦,是这本书真的很全面。内容优质。
1 MySQL 执行计划
在 MySQL 中可以通过 explain 关键字模拟优化器执行 SQL 语句,从而知道 MySQL 是
如何处理 SQL 语句的。
2 MySQL 整 个查询执行过程
• 客户端向 MySQL 服务器发送一条查询请求
• 服务器首先检查查询缓存,如果命中缓存,则立刻返回存储在缓存中的结果。否则进
入下一阶段
• 服务器进行 SQL 解析、预处理、再由优化器生成对应的执行计划
• MySQL 根据执行计划,调用存储引擎的 API 来执行查询
• 将结果返回给客户端,同时缓存查询结果
3 启动执行计划
EXPLAIN SELECT 投影列 FROM 表名 WHERE 条件
4 EXPLAIN 列的解释
4.1 ID
查询执行顺序:
id 值相同时表示从上向下执行
id 值相同被视为一组
如果是子查询,id 值会递增,id 值越高,优先级越高。
4.2 select_type
simple:表示查询中不包含子查询或者 union
primary:当查询中包含任何复杂的子部分,最外层的查询被标记成 primary
derived:在 from 的列表中包含的子查询被标记成 derived
subquery:在 select 或 where 列表中包含了子查询,则子查询被标记成 subquery
union:两个 select 查询时前一个标记为 PRIMARY,后一个标记为 UNION。union 出现
在 from 从句子查询中,外层 select 标记为 PIRMARY,union 中第一个查询为 DERIVED,第二个子查询标记为 UNION
unionresult:从 union 表获取结果的 select 被标记成 union result 。
4.3 table
显示这一行的数据是关于哪张表的。
4.4 type
这是重要的列,显示连接使用了何种类型。从最好到最差的连接类型为 system、const、
eq_reg、ref、range、index 和 ALL。
system:表中只有一行数据。属于 const 的特例。如果物理表中就一行数据为 ALL
const :查询结果最多有一个匹配行。因为只有一行,所以可以被视为常量。const 查询速度
非常快,因为只读一次。一般情况下把主键或唯一索引作为唯一条件的查询都是 const
eq_ref:查询时查询外键表全部数据。且只能查询主键列或关联列。且外键表中外键列中数
据不能有重复数据,且这些数据都必须在主键表中有对应数据(主键表中数据可以有没有用
到的)
ref:相比 eq_ref,不对外键列有强制要求,里面的数据可以重复,只要出现重复的数据取值
就是 ref。也可能是索引查询。
range:把这个列当作条件只检索其中一个范围。常见 where 从句中出现 between、<、in 等。
主要应用在具有索引的列中
index:这个连接类型对前面的表中的每一个记录联合进行完全扫描(比 ALL 更好,因为索
引一般小于表数据)。
ALL:这个连接类型对于前面的每一个记录联合进行完全扫描,这一般比较糟糕,应该
尽量避免。
4.5 possible_keys
查询条件字段涉及到的索引,可能没有使用。
4.6 Key
实际使用的索引。如果为 NULL,则没有使用索引。
4.7 key_len
表示索引中使用的字节数,查询中使用的索引的长度(最大可能长度),并非实际使用
长度,理论上长度越短越好。key_len 是根据表定义计算而得的,不是通过表内检索出的。
4.8 ref
显示索引的哪一列被使用了,如果可能的话,是一个常量 const。
4.9 rows
根据表统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数。
4.10 Fitered
显示了通过条件过滤出的行数的百分比估计值。
4.11 extra
MYSQL 如何解析查询的额外信息。
Distinct:MySQL 发现第 1 个匹配行后,停止为当前的行组合搜索更多的行。
Not exists:MySQL 能够对查询进行 LEFT JOIN 优化,发现 1 个匹配 LEFT JOIN 标准的行
后,不再为前面的的行组合在该表内检查更多的行。
range checked for each record (index map: #):MySQL 没有发现好的可以使用的索引,但发
现如果来自前面的表的列值已知,可能部分索引可以使用。
Using filesort:MySQL 需要额外的一次传递,以找出如何按排序顺序检索行。
Using index:从只使用索引树中的信息而不需要进一步搜索读取实际的行来检索表中的
列信息。
Using temporary:为了解决查询,MySQL 需要创建一个临时表来容纳结果。
Using where:WHERE 子句用于限制哪一个行匹配下一个表或发送到客户。
Using sort_union(...), Using union(...), Using intersect(...): 这 些 函 数 说 明 如 何 为
index_merge 联接类型合并索引扫描。
Using index for group-by:类似于访问表的 Using index 方式,Using index for group-by 表示
MySQL发现了一个索引,可以用来查 询GROUP BY或DISTINCT查询的所有列,而不要额外搜索
硬盘访问实际的表。
感谢~,欢迎点赞,分享,关注。