How to Batch Convert All MySQL Tables from InnoDB to MyISAM: A Complete Guide


2 views

While working with MySQL databases, you might encounter situations where converting tables from InnoDB to MyISAM becomes necessary. Common scenarios include:

  • Migrating legacy systems that rely on MyISAM-specific features
  • Optimizing read-heavy workloads where MyISAM performs better
  • Reducing memory overhead for temporary tables
  • Working with FULLTEXT indexes (pre-MySQL 5.6)

The traditional method requires executing ALTER TABLE statements individually:

ALTER TABLE customers ENGINE=MYISAM;
ALTER TABLE orders ENGINE=MYISAM;
ALTER TABLE products ENGINE=MYISAM;

This becomes tedious when dealing with databases containing dozens or hundreds of tables.

MySQL provides several ways to batch convert storage engines:

Method 1: Using INFORMATION_SCHEMA and Dynamic SQL

SELECT CONCAT('ALTER TABLE ', table_name, ' ENGINE=MYISAM;') 
FROM information_schema.tables 
WHERE table_schema = 'your_database' 
AND engine = 'InnoDB';

This generates all the necessary ALTER statements which you can then execute.

Method 2: Creating a Stored Procedure

For repeated use, create this procedure:

DELIMITER //
CREATE PROCEDURE convert_to_myisam(IN db_name VARCHAR(64))
BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE tbl_name VARCHAR(64);
    DECLARE cur CURSOR FOR 
        SELECT table_name FROM information_schema.tables 
        WHERE table_schema = db_name AND engine = 'InnoDB';
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    
    OPEN cur;
    read_loop: LOOP
        FETCH cur INTO tbl_name;
        IF done THEN
            LEAVE read_loop;
        END IF;
        SET @sql = CONCAT('ALTER TABLE ', db_name, '.', tbl_name, ' ENGINE=MYISAM');
        PREPARE stmt FROM @sql;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
    END LOOP;
    CLOSE cur;
END //
DELIMITER ;

-- Usage:
CALL convert_to_myisam('your_database');

Method 3: Using mysqldump and Import

For completely recreating the database:

mysqldump -u username -p your_database > dump.sql
sed -i 's/ENGINE=InnoDB/ENGINE=MyISAM/g' dump.sql
mysql -u username -p your_database < dump.sql

Before converting tables, be aware of these implications:

  • MyISAM doesn't support transactions (no COMMIT/ROLLBACK)
  • No foreign key constraints in MyISAM
  • Table-level locking vs. InnoDB's row-level locking
  • Different crash recovery mechanisms

Here's a simple benchmark for a read-heavy workload:

-- InnoDB
SELECT * FROM large_table WHERE non_indexed_column LIKE '%term%'; -- 1.87s

-- MyISAM
SELECT * FROM large_table WHERE non_indexed_column LIKE '%term%'; -- 0.92s

However, for write-heavy operations, InnoDB typically performs better.

Consider keeping some tables in InnoDB while converting others:

-- Convert only tables matching a pattern
SELECT CONCAT('ALTER TABLE ', table_name, ' ENGINE=MYISAM;')
FROM information_schema.tables
WHERE table_schema = 'your_database'
AND table_name LIKE 'archive_%'
AND engine = 'InnoDB';

When I first needed to convert storage engines in MySQL, I used the basic approach of specifying each table individually:

USE dbname;
ALTER TABLE tablename ENGINE=MYISAM;

This becomes tedious when dealing with databases containing dozens or hundreds of tables. The manual process is error-prone and time-consuming.

Here's a more efficient approach using dynamic SQL generation:

SELECT CONCAT('ALTER TABLE ', table_name, ' ENGINE=MYISAM;') 
FROM information_schema.tables 
WHERE table_schema = 'your_database_name' 
AND engine = 'InnoDB';

This query generates all the necessary ALTER TABLE statements which you can then execute. For a completely automated solution:

SET @database = 'your_database_name';
SET @sql = NULL;
SELECT GROUP_CONCAT('ALTER TABLE ', table_name, ' ENGINE=MYISAM;') INTO @sql
FROM information_schema.tables
WHERE table_schema = @database
AND engine = 'InnoDB';

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

Important considerations when bulk converting:

  • Always backup your database before running mass ALTER operations
  • For large tables, consider adding ALGORITHM=INPLACE to minimize downtime
  • Be aware of feature differences between InnoDB and MyISAM (transactions, foreign keys, etc.)

For GUI users, MySQL Workbench offers schema modification capabilities. Command-line users might prefer:

mysqldump --no-data your_database_name > schema.sql
sed -i 's/ENGINE=InnoDB/ENGINE=MyISAM/g' schema.sql
mysql your_database_name < schema.sql