explain
用于分析SQL语句的执行效率
直接执行explain SQL语句即可
查询select * from user
语句的执行效率:
show warnings
MySQL在执行过程中会对SQL语句进行优化,show warning可以查看MySQL优化后的SQL语句
EXPLAIN SELECT * FROM actor;
show WARNINGS
MySQL会以下方式进行执行
/* select#1 */ select `study`.`actor`.`id` AS `id`,`study`.`actor`.`name` AS `name`,`study`.`actor`.`update_time` AS `update_time` from `study`.`actor`
expain字段
- id: 查询优先级,可能重复,优先级越大,id值越大,例如下面那个条复杂查询,先查询派生查询,因为不先查询派生查询的话,没有数据没办法进行表查询,所以派生查询id最大,其次是子查询,子查询根据字段进行过滤查询字段结果,最后是最外层的复杂查询,上面拿两个查询完成了才能进行最外层的复杂查询。
- slect_type:SQL语句类型 primary(复杂外层查询)/simple(简单查询)/subquery(子查询)/deriverd(衍生查询)
使用expain对表进行检索,得出以下查询结果
# 关闭合并优化
set session optimizer_switch='derived_merge=off';
explain select (select 1 from actor where id = 1) from (select * from film where id = 1) der;
primary表示复杂查询的最外层的select语句。
也就是:
subquery表示子查询,也就是select 后面 from前面的查询被称为子查询
也就是:
derived表示派生查询,衍生表就是根据SQL语句查询结果当表来使用的表,from之后的内容
也就是:
- type
SQL查询时,查询的范围,ALL性能最差,因为得需要全表扫描才能查询到最后结果。system性能最好。
system < const < eq_ref - null: 在进行查询是没有访问表或没有访问索引。
在执行以下SQL语句时,MySQL优化器会去表索引树中直接找到第一个值或最后一个值从而不访问表直接返回。
EXPLAIN SELECT MIN(id) FROM actor;
如果不访问表也会直接显示null
explain select 1;
- const: 主键和唯一索引精确匹配时或是多表join查询时索引与中间表完全匹配也会显示const,const通常是实际开发中,查询效率最好的,因为在一般情况下,一张表只有一条记录 或是不差表直接查结果的情况太少了。
EXPLAIN SELECT * FROM actor WHERE id = 1
- system: 如果查询表只有一条数据则是system。
EXPLAIN SELECT * from (SELECT * FROM actor WHERE id = 1) t1
内层查询结果只有一条记录,根据内存查询结果在进行查询也是只有一条记录,所以type会是System。
- eq_ref: 只有在左表索引与右表全部匹配则会显示eq_ref。
左表的id索引与右表中间表全部匹配。
EXPLAIN SELECT * FROM film_actor t1 JOIN actor t2 ON t2.id = t1.actor_id;
如果在进行多表的连接查询则会有一张表没办法使用索引查询,如下所示:
EXPLAIN SELECT
*
FROM
film_actor t1
JOIN actor t2 ON t2.id = t1.actor_id
JOIN film t3 ON t3.id = t1.film_id;
在Extra中有标注Using where; Using join buffer (hash join),这个信息表示MySQL优化器在执行过程中利用Using join 技术新建了一张表与缓存中的数据进行查询,从而左右表索引没有关联起来,所以会显示ALL。
如果想要使用索引匹配的话,可以使用STRAIGHT_JOIN来确定join多表查询的顺序,不使用MySQL优化器进行优化直接进行查询
EXPLAIN SELECT
*
FROM
film_actor t1
STRAIGHT_JOIN actor t2 ON t2.id = t1.actor_id
STRAIGHT_JOIN film t3 ON t3.id = t1.film_id;
- ref: 与equ_ref不同的时,ref使用的不是唯一索引或是主键索引,而是使用普通索引。
EXPLAIN SELECT * FROM film WHERE `name` = "film0"
- range: 范围查询,录入in、between、>、<等。
EXPLAIN SELECT * FROM film_actor WHERE id > 1

-
index: 二级索引查询
由于二级索引查询效率比主键索引要高,如果可以根据二级索引就能找到表的数据,那么MySQL会有限使用二级索引来进行查询。主键索引查询慢的原因是,主键索引绑定了一整列的数据 -
All: 全表扫描。
possible_keys字段
可能用到的索引。
key字段
用到的索引。
key_lens字段
命中索引长度,如果字段属性不为空,则需要有个字段来记录是否为空,会在key_lens中进行显示。
ref字段
关联表字段,如果是常量,则会显示const。
EXPLAIN SELECT * FROM film_actor t1, film t2, actor t3 WHERE t1.actor_id = t3.id
多表查询关联actor_id根据actor_id检索数据则会显示actor的id
Extra字段
拓展字段,一般会展示额外信息,
-
Using Index: 使用覆盖索引。
如果可以根二级索引能拿到表的所有数据,MySQL为了性能会优先使用覆盖索引。 -
Using where: 使用where查询
EXPLAIN SELECT * FROM actor WHERE name = "a"
- Using index condition: 查询的列没有完全覆盖索引,例如多表联查时,对索引字段进行范围查询会出现这种情况。
EXPLAIN SELECT * FROM film_actor WHERE film_actor.film_id > 1
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律