查表大小不能直接看DATA_LENGTH,因为它仅表示B+树叶子节点中有效数据的近似字节数,不含索引、碎片及行头开销,也不反映磁盘真实占用;真正磁盘占用需结合DATA_LENGTH+INDEX_LENGTH+DATA_FREE(独立表空间时可忽略DATA_FREE)。

查表大小为什么不能直接看 DATA_LENGTH?
因为 information_schema.TABLES 里显示的 DATA_LENGTH 只是数据页实际存储的数据字节数,不包含索引、碎片、行头开销,也不反映磁盘上真实占用(比如 InnoDB 表空间未收缩时会虚高)。你执行 ALTER TABLE ... ENGINE=InnoDB 或大量 DELETE 后,DATA_LENGTH 可能远小于 DATA_FREE,但磁盘空间没释放——这是最常被误读的一点。
-
DATA_LENGTH:B+ 树叶子节点中「有效数据」的近似字节数(不含索引) -
INDEX_LENGTH:该表所有索引(含主键)占用的字节数 -
DATA_FREE:分配但未使用的空间(单位字节),仅对共享表空间或未启用innodb_file_per_table有意义 - 真正反映磁盘占用的是
DATA_LENGTH + INDEX_LENGTH + DATA_FREE的总和,但仅当表在独立表空间(.ibd文件)中时,DATA_FREE才可忽略(因为文件大小 ≈DATA_LENGTH + INDEX_LENGTH)
用 information_schema.TABLES 查单表或库级大小的正确写法
别直接 SELECT *,要过滤引擎、排除视图,并按需转换单位。常见错误是漏掉 TABLE_SCHEMA NOT IN ('information_schema', 'performance_schema', 'mysql', 'sys'),导致结果混入系统表统计。
- 查某个库下所有表大小(MB):
SELECT TABLE_NAME, ROUND((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024, 2) AS size_mb FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'your_db_name' AND ENGINE = 'InnoDB' ORDER BY size_mb DESC;
- 查某张表详细空间分布:
SELECT TABLE_NAME, ENGINE, DATA_LENGTH, INDEX_LENGTH, DATA_FREE, TABLE_ROWS FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'your_db_name' AND TABLE_NAME = 'your_table_name';
-
TABLE_ROWS是估算值(尤其 InnoDB),不准;真要精确行数请用COUNT(*),但大表慎用
SHOW TABLE STATUS 和 information_schema.TABLES 有啥区别?
本质一样——SHOW TABLE STATUS 底层就是查 information_schema.TABLES,但默认只返回当前数据库的表,且字段名不同(比如 Data_length vs DATA_LENGTH),还多出 Update_time、Collation 等非空间相关字段。性能上无差异,但 SHOW TABLE STATUS 不支持跨库 WHERE,灵活性差。
- 想快速看当前库各表大小,
SHOW TABLE STATUS LIKE 'xxx'更快打字 - 要做聚合统计(比如“哪个库总空间最大”),必须用
information_schema.TABLES,因为能 GROUP BYTABLE_SCHEMA -
SHOW TABLE STATUS对临时表、分区表子分区不显示完整信息,information_schema.TABLES同样受限,但至少字段定义一致
为什么 information_schema.TABLES 有时查不到刚建的表?
不是缓存问题,是权限或事务隔离导致的。如果你用低权限账号(比如只给了 SELECT 权限但没给 PROCESS 或 SHOW DATABASES),information_schema.TABLES 会跳过你没权限访问的库——哪怕表就在当前库。另一个坑是:在事务中建表后立刻查 information_schema,某些 MySQL 版本(如 5.7)可能因元数据锁未释放而看不到新表。
- 确认账号有
SELECT权限 oninformation_schema.*,且能访问目标TABLE_SCHEMA - 避免在长事务里建表后立即查空间——先
COMMIT或断开重连 - MySQL 8.0+ 引入了
INFORMATION_SCHEMA.INNODB_TABLESPACES,可查更底层的表空间文件路径和真实大小,但需要额外权限PROCESS


















