本文是关于在学习《高性能 Mysql》附录 D 中关于 Explain 如何获取执行计划信息相关总结。MySQL 提供了一个 EXPLAIN 命令,它能够对 SELECT 语句进行分析,获取优化器对当前查询的执行计划,以供开发人员针对相关 SQL 进行优化。在 SELECT 语句前加上 Explain 就能够查看到相关信息, 例如:mysql
EXPLAIN SELECT * from user_info WHERE id < 300;
复制代码
SELECT 查询的标识符. 每一个 SELECT 都会自动分配一个惟一的标识符.sql
select_type 表示了查询的类型, 它的经常使用取值有:segmentfault
查询的是哪一个表,mysql 查询优化器执行的关联顺序并不和咱们写 SQL 时关联的顺序一致,下面咱们讲一下 Mysql 是如何对关联查询做优化的:性能优化
type 字段比较重要, 它提供了判断查询是否高效的重要依据依据. 经过 type 字段, 咱们判断这次查询是全表扫描仍是索引扫描等,type 类型的性能比较,一般来讲, 不一样的 type 类型的性能关系以下:bash
ALL < index < range < ref < eq_ref < const < system < NULL服务器
# 由于表中backend_user是主键,因此子查询里最多能够选出一条数据,因此最外层查询的type是system,里层查询的type是const
explain select * from (select * from backend_user where id = 1) a;
复制代码
# 虽然是都是范围查询,其实第二个查询时多个等值条件查询
# 对于第一个查询,mysql 没法再使用该列后面的其它查询索引了,而第二个则能够继续使用索引
select id from actor where id > 45 and class_id = 3;
select id from actor where id in (44, 47, 48) and class_id = 3;
复制代码
这次查询中可能选用的索引,这些索引列是根据查询的列以及比较操做符来判断的,可能在后续的真实查询中没有用到也有可能性能
这次查询中确切使用到的索引,若是在 possible_keys 中没有出现而在 key 中出现,说明优化器可能出于另外缘由好比选择覆盖索引,因此 possiable_keys 揭示了哪个索引有助于高效进行查找,而 key 显示了采用哪个索引能够最小化查询成本。学习
表示查询优化器使用了索引的字节数. 这个字段能够评估组合索引是否彻底被使用, 或只有最左部分字段被使用到,好比咱们建了一个组合索引(col1, col2),那么以下两条查询虽然用到的都是这个组合索引,可是对应的key_len的只是不同的。key_len 显示了在索引字段中可能的最大长度,而不是数据使用的实际字节数优化
select * from table1 where col1 = 1;
select * from table1 where col1 = 1 and col2 = 2;
复制代码
这一列显示了以前的表在 key 列记录的索引中查找值所用的列或者常量ui
rows 也是一个重要的字段. MySQL 查询优化器根据统计信息, 估算 SQL 要查找到结果集须要扫描读取的数据行数。这个值很是直观显示 SQL 的效率好坏, 原则上 rows 越少越好。
filtered 是在 MYSQL 5.1 中加进来的,在使用 EXPLAIN EXTENDED 时出现,表示此查询条件所过滤的数据的百分比,将 rows 除以 filtered 能够估算出整个表数据行数。
EXplain 中的不少额外的信息会在 Extra 字段显示, 常见的有如下几种内容:
当 Extra 中有 Using filesort 时, 表示 MySQL 需额外的排序操做, 不能经过索引顺序达到排序效果. 通常有 Using filesort, 都建议优化去掉, 由于这样的查询 CPU 资源消耗大。 可是 Explain 不会告诉你 Mysql 将使用文件排序仍是内存排序:
-- 好比咱们创建索引为:KEY `user_product_detail_index` (`user_id`, `product_name`, `productor`),那么以下两个查询
EXPLAIN SELECT * FROM order_info ORDER BY product_name; -- Using filesort,不能经过索引进行排序,须要优化
EXPLAIN SELECT * FROM order_info ORDER BY user_id, product_name;-- 无 Using filesort,经过索引进行排序,优化成功
复制代码
"覆盖索引扫描", 表示查询在索引树中就可查找所需数据, 不用扫描表数据文件, 每每说明性能不错
这意味着 Mysql 服务器在存储引擎检索行后再进行过滤,通常出现 “Using where” 会受益于不一样的索引
查询有使用临时表, 通常出现于排序, 分组和多表 join 的状况, 临时表多是内存临时表或者文件临时表
在 Mysql 5.1 版本中引入了 EXPLAIN PARTITIONS 能够显示查询将访问的分区状况