How to Optimize MySQL Tables and Defragment to Recover Space
MySQL OPTIMIZE TABLE command
If your application is performing lot of deletes and updates on MySQL database, then there is a high possibility that your MySQL data files are fragmented.
This will result in lot of unused space, and also might affect performance.
So, it is highly recommended that you defrag your MySQL tables on an ongoing basis.
This tutorial explains how to optimize MySQL to defrag tables and reclaim unused space.
1. Identify Tables for Optimization
The first step is to identify whether you have fragmentation on your MySQL database.
Connect to your MySQL database, and execute the following query, which will display how much unused space are available in every table.
mysql> use thegeekstuff; mysql> select table_name, round(data_length/1024/1024) as data_length_mb, round(data_free/1024/1024) as data_free_mb from information_schema.tables where round(data_free/1024/1024) > 500 order by data_free_mb; +------------+----------------+--------------+ | table_name | data_length_mb | data_free_mb | +------------+----------------+--------------+ | BENEFITS | 7743 | 4775 | | DEPARTMENT | 14295 | 13315 | | EMPLOYEE | 21633 | 19834 | +------------+----------------+--------------+
In the above output:
- This will display list of all tables that has minimum of 500MB of unused space. As we see above, in this example, there are 3 tables that has more than 500MB of unused space.
- data_length_mb column displays the total table size in MB. For example, EMPLOYEE table size is around 21GB.
- data_free_mb column displays the total unused space in that particular table. For example, EMPLOYEE table has around 19GB of unused space in it.
- All these three tables (EMPLOYEE, DEPARTMENT AND BENEFITS) are heavily fragmented and it needs to be optimized to reclaim the unused space.
From the filesystem level, you can see the size of the individual table files as shown below.
The file size will be the same as what you see under “data_length_mb” column in the above output.
# ls -lh /var/lib/mysql/thegeekstuff/ .. -rw-rw----. 1 mysql mysql 7.6G Apr 23 10:55 BENEFITS.MYD -rw-rw----. 1 mysql mysql 14G Apr 23 12:53 DEPARTMENT.MYD -rw-rw----. 1 mysql mysql 22G Apr 23 12:03 EMPLOYEE.MYD ..
In this example, the EMPLOYEE.MYD file is taking up around 22GB at the filesystem level, but it has lot of unused space in it. If we optimize this table, the size of this file should go down dramatically.

Last week during a casual conversation I overheard a colleague saying: « The Linux network stack is slow! You can’t expect it to do more than 50 thousand packets per second per core! »