查数据库总容量不能依赖information_schema.TABLES的DATA_LENGTH和INDEX_LENGTH,因其仅为估算值,真实磁盘占用需用du或ls查看文件系统;INNODB_TABLESPACES等视图也仅提供路径或页级估算,非实时大小。
查数据库总容量用 information_schema 不靠谱
直接查 information_schema.tables 算出来的“数据长度”只是 mysql 的估算值,data_length 和 index_length 来自统计信息,不是磁盘真实占用。尤其在 innodb 表启用了 innodb_file_per_table=off 时,所有表都挤在 ibdata1 里,information_schema 根本不反映实际文件大小。
- 真实容量要看操作系统层面:用
du -sh /var/lib/mysql/your_db_name/(Linux)或对应数据目录 -
information_schema更适合快速看“逻辑大小”,比如估算某张表的行数或索引占比 - 如果刚执行过
ANALYZE TABLE,TABLE_ROWS和长度字段会稍准一点,但依然不是磁盘用量
information_schema.TABLES 查单库表级大小的正确姿势
想快速对比哪些表占空间最多,得聚合 DATA_LENGTH + INDEX_LENGTH,并注意单位是字节,得手动转 MB/GB 才可读。
- 别只查
DATA_LENGTH—— 大量索引的表(比如带 JSON 字段或全文索引)INDEX_LENGTH可能比数据还大 - 过滤条件必须加
TABLE_SCHEMA = 'your_db',否则跨库结果混在一起没法用 - 排序用
ORDER BY DATA_LENGTH + INDEX_LENGTH DESC,不然默认按表名排毫无意义
SELECT TABLE_NAME, ROUND((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024, 2) AS size_mb FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'myapp' ORDER BY size_mb DESC LIMIT 10;
查表空间(Tablespace)大小不能只看 information_schema
InnoDB 表空间分系统表空间、独立表空间和通用表空间,information_schema.INNODB_SYS_TABLESPACES 能查到路径和类型,但不提供实时大小;INNODB_SYS_DATAFILES 也只给路径,没尺寸。
- 要真实大小,得结合
FILE_NAME字段去读文件系统:ls -lh /var/lib/mysql/your_db/your_table.ibd -
INNODB_SYS_TABLESPACES里SPACE_TYPE = 'General'的表空间,可能被多个表共享,单独看某张表的.ibd文件会不存在 - MySQL 8.0+ 的
information_schema.INNODB_TABLESPACES新增了FILE_SIZE和ALLOCATED_SIZE,但仅对独立表空间有效,且数值仍是页级估算
为什么 SHOW TABLE STATUS 比 information_schema 更快但更不准
SHOW TABLE STATUS LIKE 'xxx' 底层也是查 information_schema.TABLES,但它走的是缓存路径,响应快,代价是数据可能滞后几分钟——特别是大表没做 ANALYZE 时,Data_length 可能差几倍。
- 运维巡检用它扫一遍没问题,但做扩容决策前,必须补一手
du或ls -l - MyISAM 表的
DATA_LENGTH相对准,因为它的 .MYD 文件就是纯数据;InnoDB 的 MVCC、undo、buffer pool 都会让估算失真 - 如果看到
information_schema.TABLES里某张表的AVG_ROW_LENGTH是 0,大概率是统计信息失效,需要ANALYZE TABLE
真正卡住人的地方,从来不是 SQL 怎么写,而是搞不清 DATA_LENGTH 到底是“磁盘上占多少”还是“引擎说它大概有这么多”。这两个数字在 InnoDB 里经常差一个数量级。










