最准的是COUNT()但有锁表风险,information_schema.tables和SHOW TABLE STATUS的table_rows/Rows对InnoDB仅是估算值,MyISAM才准确;日常用前者粗略判断,精确统计须用COUNT()并避开高峰、优先查从库。

直接查 information_schema.tables 最快但不准
MySQL 的 information_schema.tables 表里有 table_rows 字段,看起来是现成答案。但它对 InnoDB 表只是估算值,尤其在大表或刚大批写入后,误差可能达 50% 以上——因为 InnoDB 不实时维护精确行数,而是靠采样估算。
实操建议:
- 仅用于快速粗略判断(比如“这个库是不是空的”“哪个表明显比其他大得多”)
- 查询时务必加
WHERE table_schema = 'your_db_name',否则会扫全实例元数据,慢且没必要 - MyISAM 表的
table_rows是准确的,但 MyISAM 基本不用了
示例:
SELECT table_name, table_rows FROM information_schema.tables WHERE table_schema = 'myapp' AND engine = 'InnoDB';
SELECT COUNT(*) 精确但锁表风险高
要真数,COUNT(*) 是唯一可靠方式。但它的代价很实在:InnoDB 下会走聚簇索引全扫描,大表可能秒变慢查询,还可能阻塞写操作(尤其在 REPEATABLE-READ 隔离级别下)。
实操建议:
- 避开业务高峰执行,优先用从库查(确保从库延迟低)
- 别在事务里嵌套
COUNT(*),容易拉长事务、拖累并发 - 如果只要“是否为空”,用
SELECT 1 FROM table_name LIMIT 1更轻量
示例(查单表):
SELECT COUNT(*) FROM users;
用 SHOW TABLE STATUS 看估算值+额外元信息
SHOW TABLE STATUS LIKE 'table_name' 返回的 Rows 列和 information_schema 一样是估算值,但它额外带了 Data_length、Index_length、Update_time 等字段,对容量规划和冷热判断更实用。
实操建议:
- 想同时看大小、更新时间、碎片率?这个命令比拼接多个
information_schema查询更省事 - 不支持
WHERE过滤,批量查所有表得用脚本循环或结合INFORMATION_SCHEMA - 注意
Update_time在某些配置下(如innodb_stats_on_metadata=OFF)可能不更新
示例:
SHOW TABLE STATUS IN myapp LIKE 'orders';
生产环境推荐组合方案
没有银弹。线上库该用什么方法,取决于你此刻要解决的具体问题。
实操建议:
- 日常巡检/容量报表:用
information_schema.tables+Data_length排序,关注增长异常的表 - 排查慢查询或锁等待:先看
SHOW OPEN TABLES WHERE In_use > 0,再针对性COUNT(*),别盲目扫全库 - 迁移前校验:必须用
COUNT(*),但提前在从库跑好,主库只比对结果
真正麻烦的是那些没建主键、没索引的大表——COUNT(*) 可能卡住几分钟,而 table_rows 误差又大到失去参考价值。这种时候,要么加索引优化统计路径,要么接受“估算+抽样验证”的折中方案。


















