type字段是判断索引是否生效的首要依据,效率从优到劣为:system≈const→ref→range→index→all;all表示全表扫描,index为全索引扫描,ref及以上说明有效利用索引,需结合key、rows、extra综合评估。

看 type 字段:这是判断索引是否生效的首要依据
执行效率高低,type 是最直观的信号。它描述 MySQL 如何定位数据行,顺序从优到劣是:system ≈ const → ref → range → index → ALL。
常见问题场景:
-
type = ALL:全表扫描,哪怕只有几千行,在高并发下也会明显拖慢响应;尤其当rows值远大于实际返回行数时,基本可断定没走对索引 -
type = index:走了索引但做了全索引扫描(比如SELECT * FROM t ORDER BY id且无 WHERE),比ALL略好,但仍是隐患 -
type = ref或更高:说明用了非唯一索引做等值匹配(如WHERE status = 'active'),属于健康状态
注意:type = const 不代表“一定快”,它只表示通过主键或唯一索引查到了**恰好一行**;但如果该行在磁盘深处、或需要回表大量字段,仍可能慢。
盯 key 和 possible_keys:确认优化器选了哪个索引
possible_keys 列出所有可用索引,key 显示最终选中的那个。两者不一致,或 key 为 NULL,就是典型索引失效信号。
容易踩的坑:
- 字符串条件漏引号:
WHERE user_id = 123对VARCHAR字段,会触发隐式类型转换,导致key为空 - 联合索引顺序错位:
INDEX(a, b, c),但查询用WHERE b = 1 AND c = 2,无法命中,key为NULL -
LIKE开头通配:WHERE name LIKE '%abc',即使有索引也用不上,key为空
别只信 possible_keys —— 它只是“可能”,不代表真能用;关键看 key 是否非空,以及是否符合你的查询意图。
查 rows 和 filtered:预估扫描与过滤效率
rows 表示 MySQL 预估要读取的行数(不是返回行数),越接近实际结果集越理想;filtered 表示 WHERE 条件过滤后剩余比例(0–100),值越低说明过滤越差。
典型低效组合:
-
rows = 100000+filtered = 1.0:说明几乎没过滤,靠后续逻辑硬扛,大概率该加索引或改写条件 -
rows很小但filtered极低(如 0.1):WHERE 中用了函数或表达式(如WHERE YEAR(create_time) = 2024),导致索引失效 -
rows和实际返回行数相差一个数量级:可能是统计信息过期,需执行ANALYZE TABLE
rows 是估算值,不准是常态;但它突然飙升(比如从 100 跳到 50000),往往意味着执行计划已劣化,必须干预。
扫 Extra 字段:识别隐藏开销
Extra 里藏着真正吃资源的操作,不能只看“有没有索引”,还要看“用了索引之后干了啥”。
高频危险信号:
-
Using temporary:MySQL 创建了临时表,常见于 GROUP BY、DISTINCT、含子查询的 UNION -
Using filesort:需要额外排序,即使有索引,如果ORDER BY字段不在索引最左前缀,也会触发 -
Using index condition:好消息,表示用了 ICP(索引条件下推),减少回表次数 -
Using where; Using index:最佳状态之一,说明覆盖索引+条件过滤全在索引层完成
特别注意:Using filesort 和 Using temporary 同时出现,基本等于“这个查询在大数据量下必然变慢”,优先级高于调优单个 type 字段。











