mysql explain
参考:[MySQL高级 EXPLAIN用法和结果分析](https://blog.csdn.net/why15732625998/article/details/80388236)
explain 分析
- 表的读取顺序
- 数据读取操作的操作类型
- 哪些索引可以使用
- 哪些索引被实际使用
- 表之间的引用
- 每张表有多少行被优化器查询
example sql
explain SELECT count(0)
FROM (SELECT min(h.price_normal) minPrice
FROM prod_scenic_spot s
LEFT JOIN prod_scenic_spot_homestay sh ON sh.scenic_spot_id = s.id
LEFT JOIN prod_homestay_new h ON h.id = sh.homestay_id
LEFT JOIN prod_homestay_facility_services hfs ON hfs.homestay_id = h.id
LEFT JOIN prod_homestay_card hc ON hc.homestay_id = h.id
LEFT JOIN vip_card c ON c.id = hc.card_id AND c.status = 1
WHERE h.`status` = 2
AND h.del_flag = 0
AND h.product_type = 6
AND h.one_card_pass_support = 1
GROUP BY s.id) t
结果
id|select_type|table |partitions|type |possible_keys|key |key_len|ref |rows |filtered|Extra |
--+-----------+----------+----------+------+-------------+-------+-------+-------------------------+-----+--------+------------------------------------------+
1|PRIMARY |<derived2>| |ALL | | | | |66934| 100.0| |
2|DERIVED |sh | |ALL | | | | | 81| 100.0|Using where; Using temporary |
2|DERIVED |s | |eq_ref|PRIMARY |PRIMARY|8 |guituke.sh.scenic_spot_id| 1| 100.0|Using index |
2|DERIVED |h | |eq_ref|PRIMARY |PRIMARY|8 |guituke.sh.homestay_id | 1| 5.0|Using where |
2|DERIVED |hfs | |ALL | | | | | 787| 100.0|Using where; Using join buffer (hash join)|
2|DERIVED |hc | |ALL | | | | | 21| 100.0|Using where; Using join buffer (hash join)|
2|DERIVED |c | |eq_ref|PRIMARY |PRIMARY|8 |guituke.hc.card_id | 1| 100.0|Using where |
- id :select查询的序列号,包含一组数字,表示查询中执行select子句或操作表的顺序
- select_type :查询类型 或者是 其他操作类型
- table :正在访问哪个表
- partitions :匹配的分区
- type :访问的类型
- possible_keys :显示可能应用在这张表中的索引,一个或多个,但不一定实际使用到
- key :实际使用到的索引,如果为NULL,则没有使用索引
- key_len :表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度
- ref :显示索引的哪一列被使用了,如果可能的话,是一个常数,哪些列或常量被用于查找索引列上的值
- rows :根据表统计信息及索引选用情况,大致估算出找到所需的记录所需读取的行数
- filtered :查询的表行占表的百分比
- Extra :包含不适合在其它列中显示但十分重要的额外信息
- 一般type最好要:eq_ref、ref、eq_ref_null、rang
- 遇到 extra 的 filesort 和 type 的 index 和 ALL 需要处理优化
id
select查询的序列号,包含一组数字,表示查询中执行select子句或操作表的顺序
- id相同,执行顺序由上至下
- id不同,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行
- id相同不同,同时存在
select_type
SIMPLE
:不含子查询和 union
PRIMARY
、SUBQUERY
:含子查询时,最外层的为 PRIMARY
UNION
、UNION RESULT
:UNION 是在 union 后的查询,union result 是 union 后的结果
DERIVED
:FROM 后的子查询(注意和 WHERE 后的子查询区分开来)
partition
分区,没有使用分区则为null
type
如下越左边越优秀
NULL > system > const > eq_ref > ref > ref_or_null > index_merge > range > index > ALL
NULL
:不需要查表,如 SELECT uuid(); SELECT 5 + 3;SELECT MAX(id)/MIN(id),叶子节点有序,那么直接查叶子节点的最大值或最小值
SYSTEM
:只有一行数据,const 的特例
const
:通过索引一次找到,主键索引和唯一键索引的等值查询
eq_ref
:连表查询,唯一键的字段进行关联(A.a = B.b,a、b都是唯一非空索引)
ref
:单表或连表,单表使用非唯一索引查询,多表关联时驱动表是唯一索引关联被驱动表的非唯一索引,大概是等值查询能够查询出来多条的
ref_or_null
:类似 ref,搜索为 null 值的行时
index_merge
:使用了多个索引,一般是多个 or 条件使用不同的索引列表,由于要读取多个索引,效率可能是不如range的
range
:like、范围、BETWEEN、IN、IS NULL
index
:遍历索引树,不是从根节点比较那种,而是从叶子节点从左到右遍历的那种
ALL
:类似于遍历聚集索引,每次取出的数据不仅是索引还有数据
possible_key
可能会被使用到的索引,一般以 key 为准
key
实际使用的索引列,为 null 则没有使用索引,若使用了覆盖索引,则查询的列都会出现在 key 中
rows 和 filter
rows
:估算执行大概所需查询的行数
filter
:查询的行数与总行数的比值,类似 rows,越小越好
extra
using filesort
:需要进行排序时找不到能够使用的索引,需要使用磁盘进行外部排序
using tempporary
:排序时使用了临时表,和 filesort 类似不过是内存排序,常见于 order by 和 group by
using index
:使用到了索引
using where
:? 使用了 where 但是没啥用
using join buffer
:多表连接的使用使用了 join buffer,可以调节 join buffer 的大小
impossible where
:where 条件不能筛选出数据
distinct
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix