const是主键或唯一索引的单行等值查询,要求索引字段NOT NULL且条件精确匹配;system是其特例,仅当表物理仅一行且命中主键/唯一索引时出现。

const 是主键或唯一索引的单行等值查询
当 WHERE 条件精确匹配主键(PRIMARY KEY)或非空唯一索引(UNIQUE NOT NULL),且确定只返回 1 行时,MySQL 将该查询优化为常量访问,type 显示为 const。
它不依赖表大小,只依赖“是否能通过索引一步定位到唯一一行”。例如:
EXPLAIN SELECT * FROM film WHERE id = 1;
只要 id 是主键,哪怕表有千万行,type 仍是 const。
-
const的关键前提是:索引字段必须是NOT NULL,否则可能退化为ref - 若条件含函数(如
WHERE YEAR(created_at) = 2024),即使字段有索引,也无法触发const - 联合索引只有所有列都参与等值匹配、且最左前缀完整时,才可能达成
const(极少见,通常需覆盖整个唯一约束)
system 是 const 的特例:单行表 + 主键/唯一索引查询
system 不是“更快的 const”,而是 const 在一种极端场景下的子集:表本身只有一行数据,且查询仍走主键或唯一索引。
典型场景是配置表、状态字典表等静态单记录表。例如:
EXPLAIN SELECT * FROM config WHERE id = 1;
其中 config 表仅存 1 行,id 是主键 —— 此时 type 为 system。
-
system必须同时满足两个条件:表物理上只有 1 行 + 查询命中主键/唯一索引 - 如果表只有一行但没建主键(比如用
MyISAM且无索引),type会是ALL,不是system -
system理论上可跳过磁盘 I/O(数据已加载进内存),但实际中极少遇到,多数是调试或压测环境里人工构造的
为什么看到 system 很少?因为它非常苛刻
真实业务系统里,几乎不存在长期稳定维持“仅 1 行 + 有主键 + 常被等值查询”的表。哪怕配置表,也常因运维扩写、历史遗留或误操作多出几行。
更常见的是:你本以为是 system,结果 EXPLAIN 显示 const —— 这说明表不止一行;或者显示 ALL —— 说明没建主键,或查询条件没对齐索引。
- 用
SELECT COUNT(*) FROM table_name确认行数,别信注释或文档 -
SHOW CREATE TABLE table_name查主键和索引定义,注意UNIQUE是否带NOT NULL -
system和const都要求优化器能静态推断出结果唯一性,一旦涉及子查询、变量、IN列表长度 > 1,就降级为ref或更低
NULL 类型和 const/system 的关系容易混淆
NULL 在 type 列中代表“无需访问表或索引”,比如 SELECT 1+1 或 SELECT MIN(id) FROM empty_table —— 它和 const/system 完全不同源。
const 和 system 是“访问了索引并确认只有一行”,而 NULL 是“根本没访问任何存储引擎”。别因为都带“常量”字眼就混为一谈。
-
EXPLAIN SELECT NOW()→type: NULL,因为不查表 -
EXPLAIN SELECT * FROM film WHERE id = 1→type: const,因为查了主键索引 - 二者性能差异微乎其微,但语义完全不同:一个是“免查”,一个是“快查”


















