內存表使用哈希散列索引把數據保存在內存中,因此具有極快的速度,適合緩存中小型數據庫,但是使用上受到一些限制,以下是藍草使用的一些感受。
1、heap對所有用戶的連接是可見的,這使得它非常適合做緩存。
2、僅適合使用的場合。heap不允許使用xxxTEXT和xxxBLOB數據類型;只允許使用=和<=>操作符來搜索記錄(不允許& lt;、>、<=或>=);不支持auto_increment;只允許對非空數據列進行索引(not null)。
注:操作符 “<=>” 說明:NULL-safe equal.這個操作符和“=”操作符執行相同的比較操作,不過在兩個操作碼均為NULL時,其所得值為1而不為NULL,而當一個操作碼為NULL時,其所得值為0而不為NULL。
3、一旦服務器重啟,所有heap表數據丟失,但是heap表結構仍然存在,因為heap表結構是存放在實際數據庫路徑下的,不會自動刪除。重啟之後,heap將被清空,這時候對heap的查詢結果都是空的。
4、如果heap是復制的某數據表,則復制之後所有主鍵、索引、自增等格式將不復存在,需要重新添加主鍵和索引,如果需要的話。
5、對於重啟造成的數據丟失,有以下的解決辦法:
a、在任何查詢之前,執行一次簡單的查詢,判斷heap表是否存在數據,如果不存在,則把數據重新寫入,或者DROP表重新復制某張表。這需要多做一次查詢。不過可以寫成include文件,在需要用該heap表的頁面隨時調用,比較方便。
b、對於需要該heap表的頁面,在該頁面第一次且僅在第一次查詢該表時,對數據集結果進行判斷,如果結果為空,則需要重新寫入數據。這樣可以節省一次查詢。
c、更好的辦法是在MySQL每次重新啟動時自動寫入數據到heap,但是需要配置服務器,過程比較復雜,通用性受到限制。
藍草目前采用的是第二種辦法。
6、一些預期可能用到的sql語句
//如果表存在,則刪除
DROP TABLE IF EXISTS `abc`;
//復制整張表xyz為heap表abc(包含所有數據)
CREATE TABLE `abc` type=heap select * from `xyz`;
//添加主鍵id
ALTER TABLE `abc` ADD PRIMARY KEY (`id`);
//添加索引username
ALTER TABLE `abc` ADD INDEX `abc` (`username`);
7.建表實例
CREATE TABLE `DB` (
`id` int(11) default NULL,
`songname` varchar(255) NOT NULL default '',
`singer` varchar(255) NOT NULL default '',
KEY `songname` (`songname`,`singer`)
) TYPE=HEAP建表時TABLE TYPE 選項也有這個表結構就是建立了內存表。如果MYSQL重啟 那內存表的數據 將會消失。但訪問速度會很快!早先問過BleakWind,他認為,給別人做的話MySQL內存表做會話比較 好一些,因為MySQL內存表做Session更容易維護(可以制作安裝腳本)。這個周末,我進行了一些測試,測試MySQL MyISAM表做會話(對時間給不給索引)、內存表做會話、MemCache做會話的效率比較。
定義會話Session類:定義會話處理器接口(Session_Handler_Interface):實現MySQL內存表Session處理器:實現MemCache會話處理器:MySQL內存表測試程序:MemCache會話測試代碼:MySQL會話表如下:
CREATE TABLE `session` (
`id` char(32) COLLATE utf8_unicode_ci NOT NULL,
`name` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
`ip` varchar(15) COLLATE utf8_unicode_ci NOT NULL,
`time` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MEMORY DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;測試結果:
MemCache:
======================================================================================
Concurrency Level: 30
Time taken for tests: 18.234375 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 2774781 bytes
Html transferred: 280000 bytes
Requests per second: 548.41 [#/sec] (mean)
Time per request: 54.703 [ms] (mean)
Time per request: 1.823 [ms] (mean, across all concurrent requests)
Transfer rate: 148.57 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 1.9 0 31
Processing: 0 53 12.1 46 328
Waiting: 0 52 11.9 46 328
Total: 0 53 12.1 46 328
Percentage of the requests served within a certain time (ms)
50% 46
66% 62
75% 62
80% 62
90% 62
95% 62
98% 62
99% 78
100% 328 (longest request)
MySQL內存表:
=================================================================================
Concurrency Level: 30
Time taken for tests: 20.375000 seconds
Complete requests: 10000
Failed requests: 4694
(Connect: 0, Length: 4694, Exceptions: 0)
Write errors: 0
Total transferred: 3118440 bytes
Html transferred: 623048 bytes
Requests per second: 490.80 [#/sec] (mean)
Time per request: 61.125 [ms] (mean)
Time per request: 2.038 [ms] (mean, across all concurrent requests)
Transfer rate: 149.45 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 1.9 0 31
Processing: 0 60 7.6 62 125
Waiting: 0 59 7.6 62 125
Total: 0 60 7.5 62 125
Percentage of the requests served within a certain time (ms)
50% 62
66% 62
75% 62
80% 62
90% 62
95% 62
98% 78
99% 78
100% 125 (longest request)
其他測試:
將MySQL實現的數據庫引擎改為 MyISAM(依然為 並發 30 測試 10000 次) 結果為:
Requests per second: 440.17 [#/sec] (mean)
Percentage of the requests served within a certain time (ms)
50% 62
66% 62
75% 78
80% 78
90% 78
95% 78
98% 78
99% 78
100% 640 (longest request)
為MyISAM表的 time 列增加索引(因為 會話表 讀寫次數幾乎相等,因此應該效果不明顯),結果為:
Requests per second: 441.08 [#/sec] (mean)
Percentage of the requests served within a certain time (ms)
50% 62
66% 62
75% 78
80% 78
90% 78
95% 78
98% 109
99% 109
100% 156 (longest request)
=================================================================================
結論:
MemCache做會話效率最高,也最靈活,但目前嘗不支持查看誰在線等功能,附加的,只能自己增加一個數組記錄在線用戶、以及最後活躍時間並實現gc等。
MySQL內存表做會話效率也相當的高,另外一個有點是,MySQL內存表似乎更穩定,longest request (125ms)明顯的短於 MemCache的(328ms)。不過缺點是,存儲的字段數以及字段長度受限。
MySQL MyISAM表做會話在這裡居然也達到了440的rps,真不簡單。不過您要是等半個小時在測試一次,您就會明白MyISAM表的缺點了,頁面幾乎崩潰。MyISAM表的缺點是,一旦其中有較多的碎片,這個數據庫幾乎都不可用了,您注釋掉 gc 的代碼在這裡貌似可以獲得更好的效率表現(^_^、當然也可以定時的Optimizer,概率觸發或者Cron定時啟動也不錯)
MyISAM表對time列增加索引對每秒完成的請求數沒什麼影響,不過有一點需要注意的是,增加索引後,每次完成 request的時間更均勻了,longest request從640ms跌到了156ms。為time列增加索引有助於讓完成請求的時間變均勻。
測試平台:
Acer ASPire 4520G:
CPU:AMD Athlon 64 * 2 TK-55
RAM: IG
OS: Windows XP sp2
Web Server: apache 2.26
PHP: PHP5.25