| 特性 | 說明 |
|---|---|
| 存儲介質 | 純內存 (RAM) |
| 索引類型 | 預設 HASH 索引 (等值查詢極快),可指定 BTREE |
| 可見性 | **所有連接共享** (全局可見),適合緩存層 |
| 生命週期 | 服務重啟 **數據清空,結構保留** |
| 最大大小 | 受 max_heap_table_size 限制 (預設 16MB) |
<、>、<=、>= 範圍查詢 (僅 = 和 <=>)AUTO_INCREMENT (5.0 版本限制,5.1+ 已支援)NOT NULL)<=> 運算子 (NULL-safe equal)SELECT 1 <=> 1; -- 1
SELECT NULL <=> NULL; -- 1 (普通 = 返回 NULL)
SELECT 1 <=> NULL; -- 0
在 MEMORY 表唯一允許的比較中,<=> 正確處理 NULL 比較。
function ensure_heap_data($table, $source_sql) {
$count = $db->get_var("SELECT COUNT(*) FROM `$table`");
if ($count == 0) {
$db->query("TRUNCATE TABLE `$table`");
$db->query($source_sql); -- 如:INSERT INTO heap SELECT * FROM source
// 或重建索引
$db->query("ALTER TABLE `$table` ADD PRIMARY KEY (`id`), ADD INDEX `idx_name` (`name`)");
}
}
// 每次查詢前調用,或封裝在 Model 層
⚠️ 額外一次 COUNT(*) 查詢開銷,可接受。
function get_heap_data($table, $source_sql) {
$data = $db->get_results("SELECT * FROM `$table` LIMIT 1");
if (empty($data)) {
$db->query("TRUNCATE TABLE `$table`");
$db->query($source_sql);
return $db->get_results("SELECT * FROM `$table`");
}
return $db->get_results("SELECT * FROM `$table`");
}
// 僅在首次為空時重建,後續直接讀取
# /etc/init.d/mysql 或 systemd service 啟動後執行
# 或 MySQL init_file 參數
# my.cnf
[mysqld]
init_file=/usr/local/mysql/init_heap.sql
# init_heap.sql 內容
TRUNCATE TABLE `cache_table`;
INSERT INTO `cache_table` SELECT * FROM `source_table`;
ALTER TABLE `cache_table` ADD PRIMARY KEY (`id`), ADD INDEX `idx_name` (`name`);
-- 安全刪除重建
DROP TABLE IF EXISTS `heap_cache`;
-- 從源表複製結構+數據建立 HEAP 表
CREATE TABLE `heap_cache` ENGINE=MEMORY SELECT * FROM `source_table`;
-- 補充主鍵與索引 (複製後丟失)
ALTER TABLE `heap_cache` ADD PRIMARY KEY (`id`);
ALTER TABLE `heap_cache` ADD INDEX `idx_username` (`username`);
-- 指定 BTREE 索引支援範圍查詢
CREATE TABLE `heap_cache` (
`id` INT NOT NULL,
`name` VARCHAR(50) NOT NULL,
PRIMARY KEY (`id`),
INDEX `idx_name` (`name`) USING BTREE
) ENGINE=MEMORY;
| 方案 | 優點 | 缺點 | 適用 |
|---|---|---|---|
| MEMORY 表 | 原生、SQL 介面、全局共享 | 重啟丟失、限制多、表鎖 | 小型熱點緩存、中間表 |
| Redis | 高性能、豐富數據結構、持久化可選、集群 | 需額外組件、非 SQL | 通用緩存、會話、排行榜 |
| MySQL InnoDB + Buffer Pool | ACID、SQL、熱數據自動內存、持久化 | 非純內存、寫入有磁盤開銷 | 核心業務表、熱點自動緩存 |
| TempTable (MySQL 8.0+) | 內存臨時表、自動溢寫磁盤、線程私有 | 僅臨時表、會話級 | 複雜查詢中間結果 |
[mysqld]
max_heap_table_size = 256M -- 單表最大內存 (需配合 tmp_table_size)
tmp_table_size = 256M -- 內部臨時表最大內存
# 實際限制取兩者較小值
MEMORY 表是把「雙刃劍」:**用對是加速器,用錯是炸彈**。認清限制、做好重啟恢復、控制規模、監控命中率,才能穩穩發揮價值。現代架構下,**Redis + InnoDB Buffer Pool 雙層緩存** 往往是更優解。