需求源自項目中的MemCache需求,開始想用MemCached(官方站點:http://memcached.org/ ),但這個在Linux下面應用廣泛的開源軟件無官方支持的Windows版本。後來看到博客園在用NorthScale Memcached Server(官方站點:http://www.couchbase.com/products-and-services/memcached),貌似共享收費,又猶豫了。其實項目裡的需求很簡單,也想自己用.Net Cache來實現,但穩定性難以評估,開發維護成本又似乎太大,沒辦法,My SQL Memory Storage成了唯一選擇,因為幾乎不怎麼需要編寫代碼。
先看官方手冊,然後寫了個簡單的性能測試。因為官方最新的文檔都是英文版的,所以譯了5.5版本 MySQL Memory Storage章節。
Memory存儲引擎將表的數據存放在內存中。Memory替代以前的Heap成為首選項,但同時向下兼容,Heap仍被支持。
Memory存儲引擎特性:
Storage limits RAM Transactions No Locking granularity Table MVCC No Geospatial data type support No Geospatial indexing support No B-tree indexes Yes Hash indexes Yes Full-text search indexes No Clustered indexes No Data caches N/A Index caches N/A Compressed data No Encrypted data Yes Cluster database support No Replication support Yes Foreign key support No Backup / point-in-time recoveryc Yes Query cache support Yes Update statistics for data dictionary YesMemory 與 MySQL Cluster的比較
希望部署內存引擎的開發者們會考慮MySQL Cluster是否是更好的選擇,參考如下Memory引擎的使用場景及特點:
但是內存表的性能受制於單線程的執行效率和寫操作時的表鎖開銷,這就限制了內存表高負載時的擴展性,特別是混合寫操作的並發處理。此外,內存表中的數據在服務器重啟後會丟失。
MySQL Cluster(集群)支持與Memory引擎同樣的功能並且提供更高的性能,同時擁有Memory不支持的更多其它功能:
關於MySQL集群與Memory引擎更多細節方面的比較,可以查看Scaling Web Services with MySQL Cluster: An Alternative to the MySQL Memory Storage Engine,該白皮書包括了這兩種技術的性能研究,並一步步指導你如何將Memory用戶遷移到MySQL集群。
每個Memory表和一個磁盤文件關聯起來。文件名由表的名字開始,並且由一個.frm的擴展名來指明它存儲的表定義。要明確指出你想要一個Memory表,可使用ENGINE選項來指定:
CREATE TABLE t (i INT) ENGINE = MEMORY;
如它們名字所指明的,Memory表被存儲在內存中,且默認使用哈希索引。這使得它們非常快,並且對創建臨時表非常有用。可是,當服務器關閉之時, 所有存儲在Memory表裡的數據被丟失。因為表的定義被存在磁盤上的.frm文件中,所以表自身繼續存在,在服務器重啟動時它們是空的。
這個例子顯示你如何可以創建,使用並刪除一個Memory表:
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;
MEMORY表有下列特征:
CREATE TABLE lookup (id INT, INDEX USING HASH (id)) ENGINE = MEMORY; CREATE TABLE lookup (id INT, INDEX USING BTREE (id)) ENGINE = MEMORY;
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*))
SET max_heap_table_size = 1024*1024; /* Query OK, 0 rows affected (0.00 sec) */ CREATE TABLE t1 (id INT, UNIQUE(id)) ENGINE = MEMORY; /* Query OK, 0 rows affected (0.01 sec) */ SET max_heap_table_size = 1024*1024*2; /* Query OK, 0 rows affected (0.00 sec) */ CREATE TABLE t2 (id INT, UNIQUE(id)) ENGINE = MEMORY; /* Query OK, 0 rows affected (0.00 sec) */
Memory存儲引擎官方論壇: http://forums.MySQL.com/list.PHP?92
分別測試比較了MySQL的InnoDB、MyIsam、Memory三種引擎與.Net DataTable的Insert以及Select性能(柱狀圖體現了其消耗時間,單位百納 秒,innodb_flush_log_at_trx_commit參數配置為1,每次測試重啟了MySQL以避免Query Cache),大至結果如下:
寫入10000條記錄比較。
讀取1000條記錄比較。