首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL Memory 存儲引擎深度解析:特性、限制、對比 Cluster 與性能實測

     編輯:MySQL 資料庫相關知識

前言

項目需高速緩存層,考察過 Memcached、Redis、.NET Cache,最終選擇 MySQL Memory 引擎——無需額外代碼、運維成本低。本文整理官方文檔(MySQL 5.5),對比 MySQL Cluster,並給出 InnoDB/MyISAM/Memory/.NET DataTable 實測數據。

一、Memory 引擎官方特性速覽

特性支持
存儲限制RAM
事務否
鎖粒度表鎖
MVCC否
B-tree 索引是
Hash 索引是(默認)
全文索引否
聚簇索引否
數據壓縮否
加密數據是
集群支持否
復制支持是
外鍵否
備份/時間點恢復是
查詢緩存是

二、Memory vs MySQL Cluster 關鍵差異

Memory 適用場景: 會話存儲、緩存層、只讀/讀多業務、極速讀寫、可接受重啟數據丟失。

Cluster 優勢:

  • 行級鎖,真正高併發寫入
  • 讀寫混合擴展性強
  • 可選磁盤持久化,重啟不丟數據
  • Shared-nothing 架構,99.999% 可用性
  • 自動分片,無需應用層分庫分表
  • 支持 BLOB/TEXT 變長類型

決策建議: 純緩存/會話、數據可重建、單機足夠 → Memory;核心業務、需持久化、高可用、水平擴展 → Cluster。

三、創建與使用 Memory 表


CREATE TABLE t (i INT) ENGINE = MEMORY;
-- 等同於舊版 HEAP,但 MEMORY 為首選術語

每張 Memory 表對應一個 .frm 定義文件。重啟後表結構保留,**數據清空**。

示例:臨時聚合統計


CREATE TABLE test ENGINE=MEMORY;
SELECT ip, SUM(downloads) AS down FROM log_table GROUP BY ip;
SELECT COUNT(ip), AVG(down) FROM test;
DROP TABLE test;

四、核心特性與限制詳解

  • 動態哈希索引: 插入 100% 動態哈希,無溢出區,刪除行進入鏈表,重用空間,無碎片問題
  • 索引限制: 每表最多 64 個索引,每索引 16 列,最大鍵長 3072 字節
  • 索引類型選擇: USING HASH(默認,等值查詢極快)或 USING BTREE(範圍查詢、高重複鍵值)
  • 非唯一鍵支持: Hash 索引允許非唯一鍵(罕見特性)
  • NULL 列可索引
  • 固定行長度: VARCHAR 存儲為定長 CHAR,**不支持 BLOB/TEXT**
  • 支持 AUTO_INCREMENT
  • 支持 INSERT DELAYED
  • 非臨時表跨連接共享

五、內存管理關鍵參數

max_heap_table_size(默認 16MB)

  • 控制單表最大內存佔用
  • CREATE TABLE 瞬間生效,生命週期內固定
  • ALTER TABLE、TRUNCATE TABLE、重啟服務會重置為全局值
  • 會話級設置:SET max_heap_table_size = 1024*1024; 後創建表限 1MB

行內存計算公式


SUM_OVER_ALL_BTREE_KEYS(max_length_of_key + sizeof(char*) * 4)
+ SUM_OVER_ALL_HASH_KEYS(sizeof(char*) * 2)
+ ALIGN(length_of_row + 1, sizeof(char*))

sizeof(char*):32位=4,64位=8。

內存回收機制

  • 刪除行**不釋放內存**,僅標記可重用
  • 僅同表插入新行時復用
  • 釋放已刪行空間:ALTER TABLE ENGINE=MEMORY 強制重建
  • 清空整表:DELETE/TRUNCATE TABLE/DROP TABLE

復制注意事項

主庫重啟後 Memory 表清空,從庫不知情仍返回舊數據。主庫首次使用該表時自動寫入 DELETE FROM 到 Binlog 同步從庫。**使用 --init-file 啟動時預熱表,可將不一致窗口縮減為零。**

六、性能測試:InnoDB vs MyISAM vs Memory vs .NET DataTable

測試環境

  • 表結構:id INT UNSIGNED AUTO_INCREMENT PK, obj CHAR(255)
  • innodb_flush_log_at_trx_commit=1
  • 每輪測試前重啟 MySQL 避免 Query Cache 干擾
  • 插入 10,000 行,查詢 1,000 行(ID 8000~9000)

測試腳本核心(C#)


// 四引擎分別測試 Insert/Select 耗時(Ticks)
// 完整腳本見原文,此處略

結果圖表

寫入10000條記錄耗時對比

讀取1000條記錄耗時對比

結論總結

  1. .NET DataTable 讀寫性能壓倒性領先(進程內,無網絡/序列化開銷)
  2. InnoDB 寫入耗時約為 MyISAM/Memory 的 5 倍(行鎖、事務、刷盤開銷),但高併發寫入優勢本測試未體現
  3. 三引擎 SELECT 性能接近,Memory 略優(純內存,無磁盤 IO)
  4. 高併發混合讀寫場景下,InnoDB 行鎖優勢明顯,Memory 表鎖成為瓶頸,需實測驗證

七、總結與建議

  • Memory 引擎**極速、零代碼接入**,適合會話、緩存、臨時統計等**可丟失、讀多寫少**場景
  • **嚴禁用於核心業務持久化數據**——重啟丟失、無事務、表鎖限制併發
  • 生產環境務必設置合理 max_heap_table_size,防止單表撐爆內存
  • 高併發寫入、需持久化、需高可用 → **直接上 MySQL Cluster 或 Redis/Memcached 集群**
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved