核心特性
- **全記憶體儲存**:資料與索引皆駐留 RAM,讀寫極快 (微秒級)
- **Hash 索引預設**:等值查詢 (
=, `<=>`) O(1),不支援範圍查詢 (<, >, BETWEEN)
- **跨連線可見**:同一個 MEMORY 表對所有 Session 可見,適合共享快取
- **重啟資料消失**:服務重啟表結構保留但資料清空
- **不支援**:
TEXT/BLOB、AUTO_INCREMENT (5.7+ 已支援)、NULL 索引欄位
適用場景
- 中小型**熱點資料快取** (字典表、配置表、權限對照)
- **Session 儲存** (高並發、資料小、可容忍重啟丟失)
- **中間結果暫存** (複雜報表多步驟計算)
- **查找表** (郵遞區號、國家代碼、枚舉值對照)
建表語法
CREATE TABLE session_cache (
session_id CHAR(32) NOT NULL PRIMARY KEY,
user_id INT UNSIGNED NOT NULL,
data VARCHAR(1024) NOT NULL,
expiry INT UNSIGNED NOT NULL,
KEY idx_expiry (expiry)
) ENGINE=MEMORY DEFAULT CHARSET=utf8mb4;
關鍵:ENGINE=MEMORY、NOT NULL 索引欄位、預設 Hash 索引 (可指定 USING BTREE 支援範圍查詢)。
重啟資料遺失應對策略
- 啟動腳本初始化:`/etc/init.d/mysql` 或 systemd `ExecStartPre` 執行 SQL 腳本重建資料
- 應用層懶加載:首次查詢發現空表 → 從持久層 (InnoDB/Redis) 回填
- 定期持久化:定時任務 `INSERT INTO persistent_table SELECT * FROM memory_table` (需權衡一致性)
Session 儲存效能實測 (作者原始數據)
| 方案 | QPS | 平均延遲 | P99 延遲 | 錯誤率 | 穩定性 |
| Memcached | 548 | 1.8ms | 328ms | 0% | 高 |
| MySQL MEMORY | 491 | 2.0ms | 125ms | 46.9%* | 極高 |
| MyISAM (無索引) | 440 | -- | 640ms | 0% | 低 (碎片導致崩潰) |
| MyISAM (time 索引) | 441 | -- | 156ms | 0% | 中 |
* MEMORY 表測試出現 4694 連線長度錯誤,疑為測試工具或驅動問題,非引擎本身故障。
關鍵發現
- **MEMORY 表穩定性優於 Memcached**:最長請求 125ms vs 328ms,無抖動
- **MyISAM 索引關鍵**:給 time 欄位加索引後 P99 從 640ms 降至 156ms,延遲分佈極大改善
- **Memcached 功能缺口**:不支援「誰在線」查詢,需自行維護在線集合
- **MEMORY 表限制**:欄位類型、長度、索引類型受限,不適合大物件儲存
最佳實務建議
- **Session 儲存首選 Redis/Memcached** (功能豐富、集群擴展、持久化選項)
- **純 MySQL 架構下**:MEMORY 表為優秀次選,搭配啟動初始化腳本
- **避免直接用 MyISAM 做 Session**:碎片累積導致效能崩塌,需定期 `OPTIMIZE TABLE` 或分區
- **監控關鍵指標**:`Qcache_hits`、記憶體使用率、表大小 (防止 OOM)
- **容量規劃**:`max_heap_table_size` 限制單表最大值 (預設 16MB,需調大)
參數配置
max_heap_table_size = 256M # 單表上限
tmp_table_size = 256M # 臨時表上限 (影響內部 MEMORY 表)
key_buffer_size = 64M # 索引快取 (MEMORY 表也用)