MySQL Table/Index Fragmentation

Fragmented tables or indexes leading to slower performance due to inefficient data access paths. This can often be mitigated by running OPTIMIZE TABLE.

When a developer notices table or index fragmentation in a MySQL database, they can take the following immediate actions:

  1. Analyze Table: Run `ANALYZE TABLE table_name;` for the affected tables. This command updates the index statistics of the tables and can help the optimizer make better choices for query plans.



  1. Optimize Table: Execute `OPTIMIZE TABLE table_name;` for the fragmented tables. This command defragments the table, which can improve performance for read and write operations. It essentially rebuilds the table and its indexes.



  1. Check Table’s Indexes and Fragmentation Levels: Before deciding on defragmentation, it might be useful to check the fragmentation level. Although MySQL does not provide a direct command like SQL Server to show fragmentation percentage, you can get an idea by comparing the `Datafree` (The space allocated by InnoDB but not currently used) with the `Datalength` (the length or size of the data file) from the `information_schema.tables` for InnoDB tables. Run the following query to get an overview:



SELECT tableschema, tablename, Datafree, Datalength,
(Data
free/Datalength)*100 as fragmentation_percentage
FROM information_schema.tables
WHERE ENGINE='InnoDB' AND table
schema NOT IN ('informationschema', 'mysql', 'performance_schema', 'sys');

This will give you an indication of which tables might benefit most from optimization.

  1. Rebuild Indexes: For MyISAM tables, the `OPTIMIZE TABLE` command also rebuilds the table's indexes. In the case of InnoDB, if you find specific indexes are fragmented, you can rebuild an index by using `ALTER TABLE tablename DROP INDEX indexname, ADD INDEX indexname(columnname);` However, be cautious with this approach as it locks the table.



  1. Consider innodbfilepertable: If not already set, enabling `innodbfilepertable` can reduce fragmentation by storing each InnoDB table and its indexes in a separate data file. This can be enabled by setting it in the MySQL configuration file (`my.cnf` or `my.ini`):



[mysqld]
innodb
fileper_table=1

Note that changes to `innodbfilepertable` take effect for new tables only. Existing tables need to be migrated to separate files manually using `ALTER TABLE tablename ENGINE=InnoDB;`.

Remember, before performing actions such as `OPTIMIZE TABLE` or rebuilding indexes on production databases, it's advisable to test these operations in a staging environment first and ensure you have up-to-date backups to avoid data loss.

Never debug

MySQL

manually again

Let Dr. Droid create custom investigation plans for your infrastructure.

Start Free POC (15-min setup) →
Automate Debugging for
MySQL
See how Dr. Droid creates investigation plans for your infrastructure.

MORE ISSUES

Made with ❤️ in Bangalore & San Francisco 🏢

Doctor Droid