最稳方式是查询information_schema.tables并过滤:select table_schema, table_name, engine from information_schema.tables where table_schema not in ('mysql','information_schema','performance_schema','sys') and engine = 'myisam'。

用information_schema.TABLES批量筛出所有MyISAM表
巡检时不能靠猜,得一次性拉出所有业务库里的MyISAM表。最稳的方式是查information_schema.TABLES,加明确过滤条件:
-
TABLE_SCHEMA NOT IN ('mysql','information_schema','performance_schema','sys')——必须排除系统库,否则结果混杂 -
ENGINE = 'MyISAM'——注意大小写,MySQL 8.0+ 默认区分,写成'myisam'会查不到 - 如果不确定库名大小写,先执行
SELECT DATABASE();复制输出值,别手敲
示例语句:
SELECT TABLE_SCHEMA, TABLE_NAME, ENGINE FROM information_schema.TABLES
WHERE TABLE_SCHEMA NOT IN ('mysql','information_schema','performance_schema','sys')
AND ENGINE = 'MyISAM';
为什么不用SHOW TABLE STATUS做全库扫描
SHOW TABLE STATUS只能查当前USE的库,没法跨库聚合。巡检时你得手动切库、执行、拼结果,漏一个库就可能漏掉关键MyISAM表。
- 它不支持
WHERE过滤,想筛MyISAM只能靠人眼扫,100张表里混一个MyISAM极易跳过 - 某些GUI工具(如Navicat)默认截断列宽,
Engine列显示为Eng...,根本看不出是啥 - 结果里
Rows字段对MyISAM是精确值,对InnoDB只是估算——这个差异本身就能帮你反向验证引擎类型
查到MyISAM表后必须立刻确认的三件事
看到ENGINE = 'MyISAM'只是起点,真正要命的是后续行为差异:
-
COUNT(*)没WHERE时是否变慢?MyISAM秒回,InnoDB可能扫全表——如果线上有这类查询突然变慢,先盯MyISAM表 - 事务是否静默失效?代码里写了
START TRANSACTION但引擎是MyISAM,MySQL不会报错,但也不会真正开启事务 - 主从延迟是否突增?MyISAM不写binlog事务标记,某些CDC工具会丢变更,尤其在高并发写入时
这些不是命令能告诉你的,得结合SQL逻辑和监控数据交叉判断。
权限不足导致查不到引擎时先看这三点
如果SELECT ... FROM information_schema.TABLES返回空或ENGINE列为NULL,大概率不是语法问题:
- 当前用户缺少对
information_schema的SELECT权限——联系DBA加GRANT SELECT ON information_schema.* TO 'user'@'%'; - 执行前没
USE任何库,又用了SHOW TABLE STATUS,会报Table 'db.t' doesn't exist或返回空 - 对象其实是视图,不是表——
information_schema.TABLES里TABLE_TYPE字段为'VIEW'时,ENGINE恒为NULL
真正容易被忽略的,是MyISAM表的AUTO_INCREMENT值重启后重置——这点在迁移前必须验,光看引擎类型不够。











