MySQL 5.5.5 起 InnoDB 成為預設引擎,但大量歷史系統仍殘留 MyISAM 表。本文解析引擎差異,提供 MyISAM 表掃描、遷移腳本生成與轉換最佳實踐。
過去 10 年證明:InnoDB 在高並發、大數據量、高可用場景全方位優於 MyISAM。大型生產環境幾無 MyISAM 蹤影。
按引擎統計:
SELECT ENGINE,
COUNT(*) AS TABLES,
CONCAT(ROUND(SUM(TABLE_ROWS)/1e6,2),'M') AS ROWS,
CONCAT(ROUND(SUM(DATA_LENGTH)/1024/1024/1024,2),'G') AS DATA_GB,
CONCAT(ROUND(SUM(INDEX_LENGTH)/1024/1024/1024,2),'G') AS IDX_GB,
CONCAT(ROUND(SUM(DATA_LENGTH+INDEX_LENGTH)/1024/1024/1024,2),'G') AS TOTAL_GB
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA NOT IN ('mysql','performance_schema','information_schema')
GROUP BY ENGINE ORDER BY TOTAL_GB DESC;
列出所有 MyISAM 表 (按大小排序):
SELECT CONCAT(TABLE_SCHEMA,'.',TABLE_NAME) AS TBL,
ENGINE,
CONCAT(ROUND(TABLE_ROWS/1e6,2),'M') AS ROWS,
CONCAT(ROUND(DATA_LENGTH/1024/1024/1024,2),'G') AS DATA_GB,
CONCAT(ROUND(INDEX_LENGTH/1024/1024/1024,2),'G') AS IDX_GB,
CONCAT(ROUND((DATA_LENGTH+INDEX_LENGTH)/1024/1024/1024,2),'G') AS TOTAL_GB
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA NOT IN ('mysql','performance_schema','information_schema')
AND ENGINE = 'MyISAM'
ORDER BY DATA_LENGTH+INDEX_LENGTH DESC;
default_storage_engine 或升級版本不會自動轉換現有表。innodb_buffer_pool_size, innodb_log_file_size, innodb_flush_log_at_trx_commit 等)。SET @DB_NAME = 'your_database';
SELECT CONCAT('ALTER TABLE `', TABLE_NAME, '` ENGINE=InnoDB;') AS SQL_STMTS
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = @DB_NAME
AND ENGINE = 'MyISAM'
AND TABLE_TYPE = 'BASE TABLE'
ORDER BY TABLE_NAME DESC;
輸出結果複製執行,或寫入檔案 source /path/to/alter.sql 批次執行。大表轉換會鎖表,建議低峰期或使用 pt-online-schema-change 線上遷移。
SHOW TABLE STATUS WHERE Engine='MyISAM' 確認清零Innodb_row_lock_waits、Innodb_buffer_pool_reads 等指標完成遷移後,記得在 my.cnf 明確設定 default_storage_engine=InnoDB 並移除 MyISAM 相關配置 (如 key_buffer_size),徹底告別舊時代。