EXPLAIN 不显示表引擎,引擎差异不影响其输出格式,但深刻影响type、key、rows、Extra等字段的含义与取值逻辑:MyISAM的rows为精确计数(无WHERE时),InnoDB依赖统计且受配置影响;Using index仅InnoDB常见,因二级索引含主键;type=ALL在MyISAM为顺序读.MYD,在InnoDB为聚簇索引遍历,性能差异显著;对比前须统一刷新统计、关闭索引下推等干扰项。

EXPLAIN 看不出 MyISAM 和 InnoDB 的引擎差异?
直接说结论:EXPLAIN 本身不显示表引擎,也不会因引擎不同而自动改变执行计划的“外观”,但引擎差异会深刻影响 type、key、rows、Extra 等字段的实际含义和取值逻辑。比如 MyISAM 没有事务和行锁,rows 常是粗略估算;InnoDB 的 rows 更依赖索引统计,且 Using index condition 这类提示只在 InnoDB 下出现。
实操建议:
- 查引擎必须先执行
SHOW CREATE TABLE `table_name`或查information_schema.tables,不能靠EXPLAIN输出反推 - 对比前确保两表结构(尤其是索引定义)完全一致,否则差异可能来自索引而非引擎
- MyISAM 对
LIKE '%abc'无法用索引,InnoDB 同样不行——别误以为“换引擎就能解决全模糊查询”
为什么 InnoDB 的 EXPLAIN 显示 Using index,MyISAM 却没有?
这是因为 Using index 表示“覆盖索引”(index-only scan),它依赖存储引擎如何组织数据。InnoDB 的二级索引叶子节点天然包含主键值,容易构造覆盖扫描;MyISAM 的索引叶子只存磁盘地址(row pointer),查非索引列必须回表读数据文件,所以几乎不会触发 Using index 提示。
实操建议:
- 若想在 MyISAM 上逼近覆盖效果,得把所有 SELECT 字段都加进联合索引——但索引体积暴涨,写入开销明显上升
- InnoDB 下
Using index是好信号,但需注意:如果key显示的是二级索引,而SELECT又含主键,InnoDB 仍可能不走覆盖(取决于优化器成本判断) - 用
EXPLAIN FORMAT=JSON查used_columns字段,比看Extra更可靠地确认是否真覆盖
type=ALL 在两种引擎下意味着什么不同?
type=ALL 都代表全表扫描,但背后代价天差地别:MyISAM 全表扫是顺序读 .MYD 文件,缓存效率高;InnoDB 全表扫本质是遍历聚簇索引的 B+ 树,随机 IO 多,且受 innodb_buffer_pool_size 影响极大。同一张表,MyISAM 可能 100ms 跑完,InnoDB 卡在 2s 以上很常见。
实操建议:
- 别只盯着
type字段是否为ALL,要结合rows和实际执行时间交叉验证 - InnoDB 下
type=ALL时,检查Extra是否含Using where:若有,说明 WHERE 条件是在引擎层后过滤,不是索引下推 - MyISAM 表若长期
type=ALL,优先考虑加索引;InnoDB 表同理,但更要确认索引选择性——低区分度索引可能让优化器主动弃用
对比执行计划时最容易忽略的配置陷阱
很多人导出两张表分别跑 EXPLAIN,结果发现 InnoDB 的 rows 总比 MyISAM 小,就认为它更快——其实只是 innodb_stats_on_metadata 关闭时,InnoDB 统计信息陈旧,rows 是预估值,而 MyISAM 的 rows 来自 .MYI 文件头的精确计数(但仅限无 WHERE 条件的 SELECT COUNT(*))。
实操建议:
- 对比前务必运行
ANALYZE TABLE刷新两表统计信息,尤其 InnoDB 表 - 关闭
query_cache_type(MySQL 5.7+ 已废弃,但老环境仍有影响),避免缓存干扰执行计划生成 - MyISAM 不支持
optimizer_switch里的多数选项,InnoDB 支持但默认开启的index_condition_pushdown会改变Extra内容——对比时记得统一关掉
真正难的不是看懂 EXPLAIN 的字段,而是理解每个字段背后引擎怎么干活、统计怎么算、优化器怎么权衡。参数一动,rows 可能变十分之一,type 却纹丝不动——这时候光盯输出没用,得去翻 INFORMATION_SCHEMA.OPTIMIZER_TRACE。










