核心價值
大表高頻查詢小子集時,**先提取子集到臨時表**,後續查詢走臨時表,避免反覆掃描大表索引/數據。
創建語法
-- 磁盤臨時表 (預設 MyISAM/InnoDB)
CREATE TEMPORARY TABLE tmp_table (
name VARCHAR(10) NOT NULL,
value INT NOT NULL
);
-- 內存臨時表 (HEAP/MEMORY 引擎,極快)
CREATE TEMPORARY TABLE tmp_table (
name VARCHAR(10) NOT NULL,
value INT NOT NULL
) ENGINE = MEMORY; -- 5.6+ 推薦 MEMORY,HEAP 為別名
生命周期與可見性
- **會話級私有**:僅當前連接可見,其他連接不可見同名臨時表
- **自動清理**:連接斷開 (斷開/超時/服務重啟) 時自動 `DROP`
- **手動刪除**:`DROP TEMPORARY TABLE tmp_table;` 釋放空間
- **遮蔽同名永久表**:同會話內同名永久表被隱藏,操作針對臨時表
HEAP/MEMORY 引擎特性與限制
| 特性 | 說明 |
| 存儲介質 | 純內存 (重啟丟失) |
| 索引類型 | 預設 HASH 索引 (等值查詢極快),可指定 BTREE |
| 不支援 | BLOB/TEXT 列、AUTO_INCREMENT (5.6+ 支援)、外鍵 |
| 行格式 | 定長 (VARCHAR 按 CHAR 存儲),佔用內存可預估 |
| 大小限制 | `max_heap_table_size` / `tmp_table_size` 较小者 |
效能權衡:何時用臨時表?
-- 場景:大表 t1 (1000萬行) 需反覆查詢某類型 100 行
-- 方案 A: 每次直查大表
SELECT * FROM t1 WHERE type = 5 AND status = 1; -- 重複掃描索引
-- 方案 B: 先建臨時表
CREATE TEMPORARY TABLE tmp_t1 AS
SELECT * FROM t1 WHERE type = 5 AND status = 1; -- 一次掃描
-- 後續 N 次查詢
SELECT * FROM tmp_t1 WHERE ...; -- 極快 (小表/內存)
決策矩陣
| 條件 | 建議 |
| 子集佔比 < 1% 且反覆查詢 > 3 次 | ✅ 臨時表大幅加速 |
| 大表已有高選擇性索引,單次查詢 | ❌ 直查更優 (省建表開銷) |
| 子集包含 BLOB/TEXT | ❌ 不能用 MEMORY,磁盤臨時表效果有限 |
| 併發極高,臨時表佔用大量內存 | ⚠️ 風險 OOM,改用 Redis/應用級緩存 |
最佳實踐
- **命名規範**:`tmp_<業務>_<隨機後綴>` 避免衝突
- **索引臨時表**:建表後 `ALTER TABLE tmp ADD INDEX idx_col (col);` 加速後續查詢
- **及時釋放**:事務/邏輯結束顯式 `DROP`,別依賴自動清理
- **監控**:`SHOW STATUS LIKE 'Created_tmp_tables';` `Created_tmp_disk_tables` (磁盤臨時表計數,應盡量為 0)