When a MySQL or MariaDB server runs low on disk space, identifying which schemas and tables consume the most storage is the first step in capacity troubleshooting. MySQL exposes table metadata—including data size (data_length), index size (index_length), and unallocated space (data_free)—through SHOW TABLE STATUS and the information_schema.TABLES view.
This guide shows how to inspect table and database sizes in MySQL and interpret the results.
Inspect Table Metadata with SHOW TABLE STATUS
To view low-level storage metrics (storage engine, row count estimate, data length, index length, and free space) for all tables in a specific database (such as zabbix):
SHOW TABLE STATUS FROM zabbix;
For large schemas, querying information_schema.TABLES is much easier to sort and filter.
Check the Size of a Single Table
Use the query below to calculate the combined data and index size (in MB) for a specific table. Replace zabbix and history with your target schema and table names:
SELECT
table_name AS `Table`,
ROUND(((data_length + index_length) / 1024 / 1024), 2) AS `Size in MB`
FROM information_schema.TABLES
WHERE table_schema = 'zabbix'
AND table_name = 'history';
Example Output
mysql> SELECT
-> table_name AS `Table`,
-> ROUND(((data_length + index_length) / 1024 / 1024), 2) AS `Size in MB`
-> FROM information_schema.TABLES
-> WHERE table_schema = 'zabbix'
-> AND table_name = 'history';
+---------+------------+
| Table | Size in MB |
+---------+------------+
| history | 0.03 |
+---------+------------+
1 row in set (0.00 sec)
List All Tables Across All Databases by Size
To rank every table on the MySQL instance from largest to smallest:
SELECT
table_schema AS `Database`,
table_name AS `Table`,
ROUND(((data_length + index_length) / 1024 / 1024), 2) AS `Size in MB`
FROM information_schema.TABLES
ORDER BY (data_length + index_length) DESC;
Example Output
+--------------------+---------------------------------------+------------+
| Database | Table | Size in MB |
+--------------------+---------------------------------------+------------+
| zabbix | items | 3.41 |
| zabbix | auditlog | 3.30 |
| zabbix | functions | 3.17 |
| zabbix | triggers | 2.67 |
| zabbix | images | 1.53 |
| zabbix | items_applications | 0.64 |
| zabbix | events | 0.56 |
| mysql | help_topic | 0.46 |
| zabbix | housekeeper | 0.19 |
| zabbix | history_uint | 0.16 |
| zabbix | auditlog_details | 0.13 |
| zabbix | opconditions | 0.03 |
| zabbix | trigger_discovery | 0.03 |
| zabbix | sysmap_url | 0.03 |
| zabbix | proxy_autoreg_host | 0.03 |
| zabbix | dbversion | 0.02 |
| zabbix | zbxe_translation | 0.01 |
...
| information_schema | TABLES | 0.00 |
| information_schema | STATISTICS | 0.00 |
| information_schema | ENGINES | 0.00 |
+--------------------+---------------------------------------+------------+
157 rows in set (0.16 sec)
Summarize Total Size per Database Schema
To aggregate total disk usage (data, indexes, and total MB) per database schema:
SELECT
table_schema AS `Database`,
ROUND(SUM(data_length) / 1024 / 1024, 2) AS `Data MB`,
ROUND(SUM(index_length) / 1024 / 1024, 2) AS `Index MB`,
ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS `Total MB`,
ROUND(SUM(data_free) / 1024 / 1024, 2) AS `Free Space MB`
FROM information_schema.TABLES
GROUP BY table_schema
ORDER BY SUM(data_length + index_length) DESC;
Operational Notes on MySQL Disk Usage
- InnoDB Fragmentation (
data_free): Deleting rows withDELETEfrees pages inside the InnoDB tablespace (data_free), but does not shrink the.ibdfile on disk unless the table is rebuilt (for example, withOPTIMIZE TABLEwheninnodb_file_per_table=ON) or truncated (TRUNCATE TABLE). - Shared System Tablespace (
ibdata1): Ifinnodb_file_per_tablewas disabled when tables were created, table data resides inside the globalibdata1file, which cannot be shrunk in-place without a logical dump and reload. - Binary Logs & Relay Logs: If filesystem usage (
df -h /var/lib/mysql) is much higher than the sum reported byinformation_schema.TABLES, check binary logs (SHOW BINARY LOGS;), slow query logs, or temporary files indatadir. - Metadata Freshness: In MySQL 8.0+, cached table statistics in
information_schemamay lag behind recent writes; runANALYZE TABLE <table_name>;if you need updated statistics.