执行计划简介
MySQL 提供了一个 EXPLAIN 命令,它可以对 SELECT 语句进行分析,并输出 SELECT 执行的详细信息,以供开发人员针对性优化。
使用explain这个命令来查看一个这些SQL语句的执行计划,查看该SQL语句有没有使用上了索引,有没有做全表扫描,这都可以通过explain命令来查看。
可以通过explain命令深入了解MySQL的基于开销的优化器,还可以获得很多可能被优化器考虑到的访问策略的细节,以及当运行SQL语句时哪种策略预计会被优化器采用。
EXPLAIN 命令用法十分简单, 在 SELECT 语句前加上 explain 就可以了, 例如:
EXPLAIN
select * from tbl_midi_file where mid_name = 'WTC1211';
参数说明
- id: SELECT 识别符。这是 SELECT 的查询序列号。
- select_type: SELECT类型。
- table: 输出的行所引用的表。
- partitions: 匹配的分区。
- type: 联接类型。
- possible_keys: 此次查询中可能选用的索引。
- key: 此次查询中确切使用到的索引。如果没有选择索引, 键是 NULL。
- key_len: 显示 MySQL 决定使用的键长度。如果键是 NULL, 则长度为 NULL。
- ref: 使用哪个列或常数与 key 一起从表中选择行。
- rows: 显示此查询一共扫描了多少行, 这个是一个估计值。多行之间的数据相乘可以估算要处理的行数。
- filtered: 显示了通过条件过滤出的行数的百分比估计值。
- Extra: 该列包含 MySQL 解决查询的详细信息或者额外的信息。
select_type列说明
- SIMPLE,表示此查询不包含 UNION 查询或子查询。
- PRIMARY,表示此查询是最外层的查询。
- UNION,表示此查询是UNION 的第二或随后的查询。
- DEPENDENT UNION,UNION 中的第二个或后面的查询语句, 取决于外面的查询。
- UNION RESULT,UNION 的结果。
- SUBQUERY,子查询中的第一个 SELECT。
- DEPENDENT SUBQUERY,子查询中的第一个 SELECT, 取决于外面的查询. 即子查询依赖于外层查询的结果。
type列说明
通常来说, 不同的 type 类型的性能关系如下
ALL < index < range ~ index_merge < ref < eq_ref < const < system
- system,表只有一行。
- const,表最多只有一行匹配,通用用于主键或者唯一索引比较时。
- eq_ref,每次与之前的表合并行都只在该表读取一行,这是除了system,const之外最好的一种,特点是使用=,而且索引的所有部分都参与join且索引是主键或非空唯一键的索引。
- ref,如果每次只匹配少数行,那就是比较好的一种,使用=或<=>,可以是左覆盖索引或非主键或非唯一键。
- ref_or_null,与ref类似,但包括NULL。
- index_merge,表示出现了索引合并优化(包括交集,并集以及交集之间的并集),但不包括跨表和全文索引。
- unique_subquery,在in子查询中,就是value in (select…)把形如“select unique_key_column”的子查询替换。
- index_subquery,同上,但把形如”select non_unique_key_column“的子查询替换。
- range,只检索给定范围的行,使用一个索引来选择行。是一个常数值的范围。
- index,该联接类型与 ALL 相同,除了只有索引树被扫描。这通常比 ALL 快,因为索引文件通常比数据文件小。
- all,全表扫描。
Extra
- 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 查询的所有列, 而不要额外搜索硬盘访问实际的表。