type 字段值从 ALL 到 system 代表单表访问效率由低到高,ALL 为全表扫描,system 为仅一行且免查找的最优方式,中间依次为 index、range、ref、eq_ref、const,越靠后扫描行数越少、索引利用越充分。

type 字段值从 ALL 到 system 代表什么
SQL 执行计划里的 type 字段,是 MySQL 优化器对 ** 单表访问方式 ** 的评级,直接反映扫描范围和效率。它不是“越靠前越好”,而是越靠后(system > const > eq_ref > …… > ALL)性能通常越优——因为越靠后的类型,意味着需要读取的行数越少、越能利用索引或主键快速定位。
注意:type=ALL不等于“全表扫描一定慢”,而 system 也不代表“绝对最快”;关键看实际扫描行数(rows)、是否回表、以及数据量级。
为什么 ALL 比 index 还差
ALL表示全表扫描:MySQL 逐行读取整张表,不走任何索引;而 index 虽然也扫描全部索引树(B+Tree 的叶子节点),但只读索引数据,通常比读完整行(含大字段、TEXT/BLOB)轻量得多,且可能避免回表。
-
ALL:引擎层读磁盘页,每行都解包,IO 和 CPU 开销高 -
index:只遍历索引 B +Tree 叶子链表,若SELECT字段全在索引中(覆盖索引),根本不用查主键聚簇索引 - 常见诱因:
WHERE条件没命中索引、索引失效(如对字段做函数操作:WHERE YEAR(create_time) = 2024)、或者建了索引但优化器误判成本选了全表
const 和 system 的区别在哪
system是 const 的特例:当查询的表只有一行(比如 information_schema 某些视图,或 MyISAM 空表),且用主键 / 唯一索引等值匹配时,优化器直接硬编码这一行结果,连“查找”动作都省了。
const则是通过主键或唯一索引一次定位到一行(例如WHERE id = 123),仍需走索引查找流程,但仅查 1 次。
- 二者都极快,但
system几乎无开销;const在EXPLAIN里常出现在驱动表(JOIN 的第一张表) - 别被
system误导:它只在极少数元数据表或特殊结构下出现,业务表几乎不可能达到 - 如果看到
type=const但rows>1,说明索引不唯一或统计信息不准,得检查SHOW INDEX和ANALYZE TABLE
如何让 type 从 ALL 变成 range 或 ref
核心是让 WHERE 条件 ** 有效命中索引最左前缀 **,并避免隐式类型转换、函数包裹等破坏索引的行为。
- 确保
WHERE字段有合适的索引:比如WHERE status = ? AND created_at > ?,应建联合索引(status, created_at),而非单独索引 - 避免
LIKE '%xxx':前置通配导致索引失效;改用LIKE 'xxx%'或考虑全文索引 - 检查字段类型一致性:比如
user_id是BIGINT,但传参用了字符串'123',MySQL 会隐式转类型,导致索引失效 - 用
FORCE INDEX临时验证:如果确定索引更好但优化器没选,可加SELECT …… FROM t FORCE INDEX (idx_status_time) WHERE ……对比rows和执行时间
真正卡住的地方往往不是“有没有索引”,而是索引字段顺序、查询条件写法、以及数据分布是否让优化器相信走索引更划算——有时候 ALL 反而是对的,尤其当表小、缓存热、或筛选条件返回 80% 行时。