Mysql Explain命令 可以查看当前的sql的执行计划
① 输出的列 和 执行成本
explain select * from orders;
当我们把explain的输出格式换成 json就会出现 query_cost 查询成本,一般mysql的优化器是成本越低就采用那个sql,所以我们要对比两个sql的性能,这个值是指的参考的。
explain format="json" select * from orders;
② 列的值的分析
type的值有 system | const | eq_ref | ref| fulltext | ref_or_null | index_merge | unique_subquery | index_subquery | range | index | all
从左到右是效率越来越低。代价越大。
Extra列的说明
注意:如果出现using join buffer可以调大join_buffer_size变量
出现using temporary 可以调大tmp_table_size
出现using filesort 可以调大 sort_buffer_size
③ 案例分析A
EXPLAIN SELECT
*
FROM
part
WHERE
p_partkey IN (
SELECT
l_partkey
FROM
lineitem
WHERE
l_shipdate BETWEEN '1997-01-01'
AND '1997-02-01'
)
ORDER BY
p_retailprice DESC
LIMIT 10;
explain 计划数据
一般我们看上面的explain数据有一个口诀,不过是80%的sql适用,也有一些其他的不适用。
从id的大往小看,id相同从上往下看。
上面的案例的查询逻辑:
① 从 id = 2记录看, 从lineitem表开始查询,属于一个range(范围)查询,我们是通过时间范围查询的。 可能使用的索引有i_l_shipdate,i_l_suppkey_partkey,i_l_partkey这些,最后使用了i_l_shipdate索引。索引的字节长度是4, 通过row列,可以看出索引查询预估有 149122 行记录, filter是过滤得到后的记录,是一个百分百,我们这里是100%;后面的extra列Using index condition; Using MRR,表示使用了索引条件和MRR。
② 先看第一个id = 1, part表ALL类型全部取出数据,行数是198403,用到了Using where; Using filesort; Using filesort是排序的意思
③ 在看第二个id = 2, 是一张临时表<subquery2>, 这个是id=2的结果,和 第一个id=1的结果关联查询。 type = eq_ref ,唯一关联查询,并建立了一个索引<auto_key>(唯一索引),跟ref字段dbt3.part.p_partkey进行关联,dbt3是数据库名称。每次关联的行数是1行
这里结合我们的前面讲的 join 的算法,第一行的id=1则是驱动表, 第二行的id=2表示内表。这里mysql把IN在内部改成join模式了。