When dealing with MySQL storage engines, the key architectural differences between MyISAM and InnoDB directly impact disk space management:
// MyISAM file structure per table
table_name.MYD // Data file
table_name.MYI // Index file
table_name.frm // Format file
// InnoDB file structure
ibdata1 // Shared tablespace
ib_logfile0 // Transaction logs
ib_logfile1
table_name.frm // Format file
MyISAM immediately releases disk space when rows are deleted, while InnoDB's behavior varies based on configuration:
-- For MyISAM
DELETE FROM large_table WHERE date < '2020-01-01';
OPTIMIZE TABLE large_table; -- Optional for defragmentation
-- For InnoDB (with innodb_file_per_table)
ALTER TABLE innodb_table ENGINE=InnoDB; -- Recreates table to reclaim space
Converting from InnoDB to MyISAM involves several technical tradeoffs:
-- Conversion example
ALTER TABLE existing_table ENGINE=MyISAM;
-- Verify conversion
SHOW TABLE STATUS LIKE 'existing_table';
Key limitations to consider:
- Loss of transactions (ACID compliance)
- No foreign key constraints
- Different locking mechanisms (table-level vs row-level)
For InnoDB, consider these approaches before converting:
-- Enable file-per-table (if not already)
SET GLOBAL innodb_file_per_table=ON;
-- Rebuild the entire tablespace
ALTER TABLE large_innodb_table ENGINE=InnoDB;
-- Monitor space usage
SELECT
table_name,
data_length,
index_length
FROM
information_schema.TABLES
WHERE
table_schema = 'your_database';
For mission-critical systems where you need both space efficiency and ACID compliance:
-- Consider using InnoDB with BARACUDA format
SET GLOBAL innodb_file_format=Barracuda;
SET GLOBAL innodb_file_per_table=ON;
SET GLOBAL innodb_large_prefix=ON;
-- Then recreate tables with compression
CREATE TABLE compressed_table (
id INT PRIMARY KEY,
data TEXT
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED;
The MyISAM and InnoDB storage engines handle disk space allocation in fundamentally different ways:
-- MyISAM creates three files per table:
tablename.MYD (data)
tablename.MYI (indexes)
tablename.frm (format)
-- InnoDB primarily uses shared tablespace files
ibdata1 (system tablespace)
ib_logfile0/1 (redo logs)
When deleting data, the engines behave differently:
-- MyISAM example (space is immediately reusable):
DELETE FROM large_table WHERE id > 1000000;
OPTIMIZE TABLE large_table; -- Reclaims disk space
-- InnoDB example (space remains allocated):
DELETE FROM huge_innodb_table WHERE date < '2020-01-01';
-- Space remains in ibdata file unless using file-per-table
Converting from InnoDB to MyISAM involves these steps:
-- 1. Create MyISAM clone
CREATE TABLE myisam_version LIKE innodb_table;
ALTER TABLE myisam_version ENGINE=MyISAM;
-- 2. Copy data
INSERT INTO myisam_version SELECT * FROM innodb_table;
-- 3. Verify integrity
SELECT COUNT(*) FROM innodb_table;
SELECT COUNT(*) FROM myisam_version;
-- 4. Swap tables (atomic operation)
RENAME TABLE innodb_table TO old_innodb, myisam_version TO innodb_table;
Before switching engines, consider these benchmarks on a 10GB table:
Operation MyISAM InnoDB
---------------- ------- -------
INSERTs/sec 1,200 850
DELETEs/sec 950 720
Disk Space Used 8.2GB 12.4GB
Crash Recovery 45sec 8sec
Instead of converting, consider these InnoDB optimizations:
-- Enable file-per-table
SET GLOBAL innodb_file_per_table=ON;
-- Reclaim space from deleted tables
ALTER TABLE large_table ENGINE=InnoDB;
-- Monitor space usage
SELECT
table_schema,
table_name,
data_length/1024/1024 AS size_mb
FROM information_schema.tables
WHERE engine='InnoDB'
ORDER BY data_length DESC;