MySQL MEMORY 引擎(舊稱 HEAP)將表數據完全存放在內存中,提供極速讀寫,但伴隨重啟數據丟失、不支持大字段、表級鎖等限制。本文系統梳理內存表特性、創建配置、索引選擇、數據持久化策略、適用場景與常見誤區。
| 特性 | MEMORY 表 | 臨時表 | InnoDB 表 |
|---|---|---|---|
| 存儲介質 | 內存(RAM) | 內存 → 超限轉磁盤 | 磁盤(Buffer Pool 緩存) |
| 重啟後數據 | 丟失(結構保留 .frm/.sdi) | 丟失 | 持久化 |
| 最大大小控制 | max_heap_table_size(默認 16M) | tmp_table_size / max_heap_table_size | innodb_buffer_pool_size + 磁盤 |
| 支持數據類型 | 固定長度行格式;不支持 BLOB/TEXT/VARCHAR(真變長) | 同 MEMORY | 全支持 |
| 索引類型 | HASH(默認) / BTREE | HASH / BTREE | BTREE(聚簇+二級) |
| 鎖粒度 | 表級鎖 | 表級鎖 | 行級鎖 |
| 事務支持 | 不支持 | 不支持 | 支持 (ACID) |
| 多連接共享 | 可見(同普通表) | 會話私有 | 可見 |
| 主從複製 | 主庫重啟/截斷 → Binlog 記錄 DELETE 同步刪除從庫數據 | 不複製 | 標準複製 |
-- 1. 創建表(MySQL 5.5+ 必須用 ENGINE)
CREATE TABLE `lookup` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`code` CHAR(20) NOT NULL,
`name` VARCHAR(100) NOT NULL, -- 實際按 CHAR 固定長度存儲
`status` TINYINT NOT NULL DEFAULT 1,
INDEX `idx_code` USING HASH (`code`), -- 等值查詢用 HASH
INDEX `idx_status` USING BTREE (`status`) -- 範圍/排序用 BTREE
) ENGINE=MEMORY DEFAULT CHARSET=utf8mb4;
-- 2. 關鍵參數調整(需重啟生效或動態 SET GLOBAL)
SET GLOBAL max_heap_table_size = 1024*1024*1024; -- 1GB 上限
-- 會話級臨時調整
SET SESSION max_heap_table_size = 256*1024*1024;
| 場景 | 推薦索引 | 原因 |
|---|---|---|
等值查找 WHERE code = 'ABC' | HASH | O(1) 定位,極快;不支持範圍/排序 |
範圍查詢 WHERE status > 1 | BTREE | 支持 >, <, >=, <=, BETWEEN, LIKE 'prefix%' |
排序 ORDER BY code | BTREE | HASH 索引無序,會觸發 filesort |
JOIN 關聯 ON t1.code = t2.code | HASH | 等值 Join,HASH 效能優於 BTREE |
可為同一列同時建立 HASH 和 BTREE 索引(不同名稱),優化器自動選擇。
內存表重啟後結構在、數據空。三種初始化方案:
# my.cnf
[mysqld]
init_file = /data/mysql/init_memory_tables.sql
# init_memory_tables.sql
USE app_db;
TRUNCATE TABLE lookup;
INSERT INTO lookup (code, name, status) SELECT code, name, status FROM source_table WHERE ...;
SELECT COUNT(*) = 0),觸發從源表同步數據。需處理併發競爭(雙重檢查鎖/分佈式鎖)。cron 定期 TRUNCATE + INSERT SELECT,適合準實時緩存場景。| ✅ 適合 | ❌ 不適合 |
|---|---|
| 熱點配置/字典表(省市區、狀態碼、枚舉值) | 核心業務持久化數據(訂單、用戶、賬戶) |
| 高頻只讀/少寫查找表(IP 庫、特徵向量索引) | 包含 BLOB/TEXT/長 VARCHAR 的寬表 |
| 中間計算臨時結果(會話級統計、複雜報表中間表) | 高併發寫入場景(表鎖瓶頸嚴重) |
| 需極低延遲(微秒級)的緩存層,替代 Redis 簡化架構 | 需事務保證的業務流程 |
INDEX idx (col) 允許 col 為 NULL。> < 操作」 → 錯誤。BTREE 索引 完全支持範圍操作。VARCHAR(100) 實際按 CHAR(100) 存儲,按最大長度分配空間。慎用大 VARCHAR。-- InnoDB → MyISAM
ALTER TABLE `t` ENGINE = MYISAM;
-- MyISAM → InnoDB
ALTER TABLE `t` ENGINE = InnoDB;
-- 任意 → MEMORY(數據會丟失,慎用)
ALTER TABLE `t` ENGINE = MEMORY;
MEMORY 引擎是「極速、易失、受限」的專用工具。核心價值:內存級延遲、HASH 索引 O(1) 等值查找、簡化架構替代外部緩存。
生產使用鐵律:
1. 僅用於可重建、可丟失、只讀為主的熱點數據。
2. 務必配置 init_file 或應用層初始化機制,保證重啟後數據自動恢復。
3. 嚴控表大小(max_heap_table_size)與列寬度,防止 OOM。
4. 高併發寫入場景禁用,表鎖會成為系統吞吐瓶頸。
正確定位,內存表是性能優化利器;濫用則是穩定性隱患。