✸ ✸ ✸
为什么需要统计表记录数
运维和开发中经常需要了解数据库各表的数据量:容量规划、慢查询排查、数据清理、迁移评估等。MySQL 提供了多种方式来统计表行数,各有优劣。
方法一:information_schema(推荐,最快)
MySQL 的 information_schema.tables 存储了所有表的元数据,包括预估行数:
-- 查看某个库所有表的行数,按行数降序
SELECT table_name, table_rows,
ROUND(data_length / 1024 / 1024, 2) AS data_mb,
ROUND(index_length / 1024 / 1024, 2) AS index_mb,
ROUND((data_length + index_length) / 1024 / 1024, 2) AS total_mb
FROM information_schema.tables
WHERE table_schema = 'your_db_name'
ORDER BY table_rows DESC;
输出示例:
+------------------+------------+---------+----------+----------+
| table_name | table_rows | data_mb | index_mb | total_mb |
+------------------+------------+---------+----------+----------+
| order_log | 12583456 | 980.00 | 320.50 | 1300.50 |
| user_action | 8234120 | 650.25 | 180.75 | 831.00 |
| product | 45230 | 8.50 | 3.20 | 11.70 |
| config | 128 | 0.02 | 0.01 | 0.03 |
+------------------+------------+---------+----------+----------+
注意:table_rows 是 InnoDB 的预估值,不是精确值。InnoDB 通过采样统计得出这个数字,误差通常在 5%-10%。对于 MyISAM 引擎,这个值是精确的。
方法二:COUNT(*)(精确但慢)
-- 精确统计单表行数
SELECT COUNT(*) FROM order_log;
-- 带条件的统计
SELECT COUNT(*) FROM order_log WHERE created_at >= '2025-01-01';
性能影响:
- InnoDB 的
COUNT(*)需要全表扫描(或全索引扫描),大表可能需要几分钟 - MyISAM 引擎有行数缓存,
COUNT(*)是 O(1) 的 - 如果只需要大概数量,用 information_schema 更合适
方法三:批量统计所有表的精确行数
如果需要精确值,可以用存储过程或脚本遍历所有表:
-- 生成统计 SQL
SELECT CONCAT('SELECT "', table_name, '", COUNT(*) FROM ', table_name, ';')
FROM information_schema.tables
WHERE table_schema = 'your_db_name';
或者用 shell 脚本:
#!/bin/bash
DB="your_db_name"
mysql -uroot -p -N -e "SHOW TABLES" $DB | while read table; do
count=$(mysql -uroot -p -N -e "SELECT COUNT(*) FROM $table" $DB)
printf "%-30s %s\n" "$table" "$count"
done | sort -t' ' -k2 -n -r
方法四:SHOW TABLE STATUS
SHOW TABLE STATUS FROM your_db_name;
-- 只看关键字段
SHOW TABLE STATUS FROM your_db_name\G
输出包含 Rows(预估行数)、Data_length、Index_length、Engine 等信息。
各方法对比
| 方法 | 精确度 | 速度 | 适用场景 |
|---|---|---|---|
| information_schema | 预估(误差5-10%) | 毫秒级 | 日常巡检、容量规划 |
| COUNT(*) | 精确 | 大表很慢 | 需要精确数字时 |
| SHOW TABLE STATUS | 预估 | 毫秒级 | 快速查看表状态 |
实用扩展查询
-- 查看整个库的总大小
SELECT table_schema AS db_name,
ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS total_mb,
SUM(table_rows) AS total_rows
FROM information_schema.tables
WHERE table_schema = 'your_db_name';
-- 查看所有库的大小排名
SELECT table_schema AS db_name,
ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS total_mb
FROM information_schema.tables
GROUP BY table_schema
ORDER BY total_mb DESC;
-- 找出没有数据的空表
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'your_db_name' AND table_rows = 0;
-- 找出没有索引的大表(潜在性能问题)
SELECT table_name, table_rows, index_length
FROM information_schema.tables
WHERE table_schema = 'your_db_name'
AND table_rows > 10000
AND index_length = 0;
总结
日常巡检用 information_schema 查预估值就够了,快且不影响性能。需要精确数字时再用 COUNT(*)。建议把 information_schema 查询加到运维巡检脚本里,定期监控各表的数据增长趋势。
✸ ✸ ✸


📜 留言板
留言提交后需管理员审核通过才会显示