Calcifer Calcifer 2
Sql

mysql统计表记录数

2018/09/28 16:34 6231 次阅读 王梓
打赏
✸ ✸ ✸

为什么需要统计表记录数

运维和开发中经常需要了解数据库各表的数据量:容量规划、慢查询排查、数据清理、迁移评估等。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_lengthIndex_lengthEngine 等信息。

各方法对比

方法精确度速度适用场景
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 查询加到运维巡检脚本里,定期监控各表的数据增长趋势。

✸ ✸ ✸

📜 版权声明

本文作者:王梓 | 原文链接:https://www.bthlt.com/note/63-Sqlmysql统计表记录数

出处:葫芦的运维日志 | 转载请注明出处并保留原文链接

📜 留言板

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