萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

MySQL 存儲引擎選型指南:為何 InnoDB 是唯一正解與 MyISAM 遷移實戰

MySQL 5.5.5 起 InnoDB 成為預設引擎,但大量歷史系統仍殘留 MyISAM 表。本文解析引擎差異,提供 MyISAM 表掃描、遷移腳本生成與轉換最佳實踐。

引擎演進與現狀

  • MyISAM:早期預設,表級鎖、不支援事務、崩潰易損壞、無法利用多核優勢。
  • InnoDB:行級鎖、MVCC、事務支援 (ACID)、自適應雜湊索引、變更緩衝、崩潰安全恢復。

過去 10 年證明:InnoDB 在高並發、大數據量、高可用場景全方位優於 MyISAM。大型生產環境幾無 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;

關鍵遷移原則

  • 全量轉換:哪怕單張小表仍用 MyISAM,參與 JOIN 時會將整個查詢降級為表級鎖,嚴重影響並發。
  • 不自動轉換:修改 default_storage_engine 或升級版本不會自動轉換現有表。
  • 轉換前準備:熟悉 InnoDB 關鍵配置 (innodb_buffer_pool_size, innodb_log_file_size, innodb_flush_log_at_trx_commit 等)。

生成轉換 SQL 腳本

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),徹底告別舊時代。

copyright © 萬盛學電腦網 all rights reserved