使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理输入的SQL语句的.从而进行性能分析.
使用:
Explain + SQL语句
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
---|
select查询的序列号,包含一组数字,表示查询中执行select子句或操作表的顺序
对应能干嘛的第一条
id的三种情况
id值相同为同一组,从上往下顺序
在所有组中 id值越大,优先级越高,越被先执行
查询的类型
select_type | 描述 |
---|---|
simple | 简单的select查询,查询中不包含子查询或者union |
primary | 查询中若包含任何复杂的子部分,最外层则被标记为此 |
subquery | 在select或where列表中包含了子查询的查询 |
derived | 在from列表中包含的子查询被标记为deriver,MySQL会递归这些子查询,把结果放进临时表里 |
union | 若第二个select出现在union之后,则被标记为union;若union包含在from子句的子查询中,外层select将被标记为derived |
union result | 从union表获取结果的select |
这一行数据是关于哪张表的
访问类型排列,显示查询使用了何种类型访问.
最好到最差依次是(常用)
system > const > eq_ref > ref > range > index > ALL
完整
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
一般来说,查询至少得保证到range级别,最好能达到ref,
type | 描述 |
---|---|
system | 表只有一行记录(等于系统表),这是const类型的特例 |
const | 表示通过一次索引就找到了,const用于比较primary key或者unique索引.因为只匹配一行数据,所以很快将主键至于where列表中.MySQL就能将该查询转换为一个常量 |
eq_ref | 唯一性索引扫描,某个匹配单独值只有一行记录 |
ref | 非唯一性索引扫描,返回匹配某个单独值的所有行 |
range | 只检索给定范围的行,使用一个索引来选择行(where id between … 就是使用了带有索引的id来划分了一个检索范围) |
index | 遍历索引树检索(select id from t1就是遍历的索引树(id建有索引)) |
ALL | 全表遍历检索 |
显示可能应用在这张表中的索引,一个或多个.
查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被实际使用到
实际使用的索引,若为NULL,则没用使用索引,
查询中若使用了覆盖索引,则该索引仅出现在key列表中
索引中使用的字节数,显示的是最大可能长度,并非实际使用长度,即key_len是通过表定义计算出的,并非表内检索出的.在不损失精度的情况下,值越小越好
用的什么值来检索索引
这里第二列ref为shared.t2.con1和const
在where第一个条件里匹配t1.col1时使用t2.col1,所以为shared.t2.con1
where第二个条件里匹配t1.col2用了一个常数,所以为const
根据表统计信息及索引选用情况,大致估算出找到所需的记录需要读取的行数
包含不适合在其他列中显示但十分重要的额外信息
描述 | 影响 | |
---|---|---|
Using filesort | 排序时产生,排序时使用了一个外部索引排序.无法利用表内索引进行排序.(排序时不是按照索引顺序直接读取,而是找到结果集后再次排序) | 降低性能(多做了一次排序操作) |
Using temporary | 使用了临时表存储中间结果(order by) | 降低性能(增加了内存消耗) |
Using index | 使用了覆盖索引,避免了访问表的数据行若同时出现using where 表明索引用来执行索引键值的查找若非,则表明索引用来读取数据而非执行查找 | 提升性能,避免了访问数据行 |
Using where | 表使用了where过滤 | |
Using join buffer | 使用了连接缓存 | |
impossible where | where子句的值恒为false,不能用来获取元祖 | |
distinct | 在找到第一个匹配项后就停止检索 |