explain/desc
约 1148 字大约 4 分钟
2025-07-07
语法
explain + SQL 语句(select 语句)
desc + SQL 语句(select 语句)
## 例如: explain select * from t3 where id=1;
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+
explain执行计划中包含的信息如下:
- id: 查询序列号
- select_type: 查询类型
- table: 表名或者别名
- partitions: 匹配的分区
- type: 访问类型
- possible_keys: 可能用到的索引
- key: 实际用到的索引
- key_len: 索引长度
- ref: 与索引比较的列
- rows: 估算的行数
- filtered: 按表条件筛选的行百分比
- Extra: 额外信息
select_type
常见类型及其含义
- SIMPLE:不包含子查询或者 UNION 操作的查询
- PRIMARY:查询中如果包含任何子查询,那么最外层的查询则被标记为 PRIMARY
- SUBQUERY:子查询中第一个 SELECT
- DEPENDENT SUBQUERY:子查询中的第一个 SELECT,取决于外部查询
- UNION:UNION 操作的第二个或者之后的查询
- DEPENDENT UNION:UNION 操作的第二个或者之后的查询,取决于外部查询
- UNION RESULT:UNION 产生的结果集
- DERIVED:出现在 FROM 字句中的子查询
type
常见类型及其含义
- system:这是 const 类型的一个特例,只会出现在待查询的表只有一行数据的情况下
- consts:常出现在主键或唯一索引与常量值进行比较的场景下,此时查询性能是最优的
- eq_ref:当连接使用的是完整的索引并且是 PRIMARY KEY 或 UNIQUE NOT NULL INDEX 时使用它
- ref:当连接使用的是前缀索引或连接条件不是 PRIMARY KEY 或 UNIQUE INDEX 时则使用它
- ref_or_null:类似于 ref 类型的查询,但是附加了对 NULL 值列的查询
- index_merge:该联接类型表示使用了索引进行合并优化
- range:使用索引进行范围扫描,常见于 between、> 、< 这样的查询条件
- index:索引连接类型与 ALL 相同,只是扫描的是索引树,通常出现在索引是该查询的覆盖索引的情况
- ALL:全表扫描,效率最差的查找方式
从下到上,性能从差到好
Extra列
该列包含MySQL解决查询的详细信息,有以下几种情况:
Using where:不用读取表中所有信息,仅通过索引就可以获取所需数据,这发生在对表的全部的请求列都是同一个索引的部分的时候,表示mysql服务器将在存储引擎检索行后再进行过滤
Using temporary:表示MySQL需要使用临时表来存储结果集,常见于排序和分组查询,常见 group by ; order by
Using filesort:当Query中包含 order by 操作,而且无法利用索引完成的排序操作称为“文件排序”
-- 测试Extra的filesort
explain select * from emp order by name;
Using join buffer:改值强调了在获取连接条件时没有使用索引,并且需要连接缓冲区来存储中间结果。如果出现了这个值,那应该注意,根据查询的具体情况可能需要添加索引来改进能。
Impossible where:这个值强调了where语句会导致没有符合条件的行(通过收集统计信息不可能存在结果)。
Select tables optimized away:这个值意味着仅通过使用索引,优化器可能仅从聚合函数结果中返回一行
No tables used:Query语句中使用from dual 或不含任何from子句
-- explain select now() from dual;
当一条sql语句提交给mysql数据库进行查询的时候需要经历以下几步
- 先在where解析这一步把当前的查询语句中的查询条件分解成每一个独立的条件单元
- mysql会自动将sql拆分重组
- 然后where条件会在B-tree index这部分进行索引匹配,如果命中索引,就会定位到指定的table records位置。如果没有命中,则只能采用全部扫描的方式
- 根据当前查询字段返回对应的数据值
总结:
EXPLAIN不会告诉你关于触发器、存储过程的信息或用户自定义函数对查询的影响情况
EXPLAIN不考虑各种Cache
EXPLAIN不能显示MySQL在执行查询时所作的优化工作
部分统计信息是估算的,并非精确值
EXPALIN只能解释SELECT操作,其他操作要重写为SELECT后查看执行计划。
mysql索引失效的常见9种原因详解
贡献者
更新日志
2025/7/7 10:46
查看所有更新日志
c1ab9
-elk&clickhouse&redis&mongdb&etcd于