MySQL 5.5 起 InnoDB 成為默認引擎,但 MyISAM 在特定場景仍有生存空間。本文提煉 9 大核心差異,提供場景化選型建議。
| # | 維度 | MyISAM | InnoDB | 影響 |
|---|---|---|---|---|
| 1 | 事務支持 | ❌ 不支持 | ✅ 完整 ACID | 金融、訂單、庫存等強一致性業務**必選 InnoDB** |
| 2 | 鎖粒度 | 🔒 表鎖 | 🔓 行鎖 (索引生效時) | 高並發寫入 **InnoDB 吞吐量碾壓 MyISAM** |
| 3 | 外鍵約束 | ❌ 不支持 | ✅ 支持 | 數據完整性由數據庫層保證,減少應用邏輯 Bug |
| 4 | 默認引擎 | 5.5 前默認 | 5.5+ 默認 | 新建表無指定則用 InnoDB |
| 5 | 全文索引 | ✅ 早期支持 | 5.6+ 支持 | 5.6 前全文搜索需 MyISAM;現代版本無差異 |
| 6 | COUNT(*) 性能 | ⚡ O(1) 讀計數器 | 🐢 O(N) 掃描 (MVCC 可見性) | 頻繁統計總量場景 MyISAM 有優勢,帶 WHERE 同樣慢 |
| 7 | 自增列索引要求 | 允許聯合索引中包含自增列 | **自增列必須為索引首列或單列索引** | 建表設計需遵循 InnoDB 規則 |
| 8 | TRUNCATE/清空表 | ⚡ 重建表,極快 | 🐢 逐行刪除 (5.7+ 優化為快速截斷) | 大表清空 MyISAM 秒級,InnoDB 需關注版本差異 |
| 9 | 行鎖升級風險 | 無 (只有表鎖) | ⚠️ 無索引/全表掃描 → 表鎖 | InnoDB 需嚴格保證 WHERE 條件走索引 |
REPAIR TABLE 甚至數據丟失
-- MyISAM:表元數據存儲行數
SHOW TABLE STATUS LIKE 't1'; -- Rows: 1000000 (即時)
-- InnoDB:需掃描聚簇索引葉子頁
SELECT COUNT(*) FROM t1; -- 全掃描
-- 優化:維護計數表、Redis 緩存、近似值 SHOW TABLE STATUS
文中提到「個人博客系統推薦 MyISAM,因為主要讀寫、少鏈式操作」。**此建議已過時**,現代博客系統(WordPress、Typecho、Ghost、Hexo+SQL)均默認/強制 InnoDB,原因:
結論:除非極特殊的只讀靜態站點,**所有生產業務表統一使用 InnoDB**。
-- 1. 停寫或低峰期
-- 2. 轉換引擎(重建表,鎖表時間長,大表用 pt-osc)
ALTER TABLE blog_posts ENGINE=InnoDB;
ALTER TABLE comments ENGINE=InnoDB;
-- 3. 重建索引(InnoDB 聚簇索引自動按主鍵組織)
-- 檢查主鍵設計:無主鍵表會生成隱藏 6 字節 row_id,性能差
ALTER TABLE blog_posts ADD COLUMN id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;
-- 4. 調整參數
innodb_buffer_pool_size = 70% RAM
innodb_log_file_size = 1G
innodb_flush_log_at_trx_commit = 1
-- 5. 驗證
SHOW TABLE STATUS WHERE Engine='InnoDB';
MyISAM 與 InnoDB 的 9 大差異本質反映了**無事務表鎖架構**與**事務行鎖 MVCC 架構**的代際差距。現代 MySQL 架構中,InnoDB 以**事務安全、高並發、崩潰恢復、生態完善**全方位超越 MyISAM。選型原則簡單:**業務表用 InnoDB,極少數只讀分析表可評估 MyISAM/ColumnStore/ClickHouse**。