MySQL內存表使用技巧
首先,我們來說一下什么是內存表,所謂內存表,是指整個數據庫表都常駐在內存中的表,相對于普通表而言,內存表存儲數據在內存中,而普通表存儲在硬盤中。那么內存表到底有什么特點呢?下面我們來詳細地分析一下。
1.MySQL內存表要怎樣創建呢?
首先,我們先來學習一下到底要怎樣創建一個內存表呢?方法很簡單,就跟普通表差不多,唯一的差異是,內存表所使用的數據庫引擎是內存。如下:
CREATE TABLE `test` ( `id` char(5) NOT NULL, `username` varchar(15) COLLATE utf8_unicode_ci DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MEMORY DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
我們普通表的引擎一般是InnoDB,我們要使用內存表,就必須把引擎設置成MEMORY。內存表的結構存放在磁盤上,擴展名為.frm, 所以重啟不會丟失。但是數據是存儲在內存當中,所以重啟之后,表數據會全部丟失。
2.MySQL內存表到底有什么限制?
如果你平時設計數據庫表的時候,有喜歡使用varchar類型的習慣的話,那么,你使用內存表的時候,就需要注意到一個細節了。我們都知道,在使用內存之前,都要先申請一段內存,那么也就是說,內存表在創建之后,每一行要使用的內存就已經固定下來了,但是我們都知道,varchar類型是動態可變長度,只有一個上限值,那么內存表會怎么做呢,先看下面一個例子:
以上面的表為例,假如有這么兩條記錄:
10000,'hellowrold!'
10001,'hey!'
普通表占用空間 -> 10000,'hellowrold!'+10001,'hey!'
內存表占用空間 -> 10000,'hellowrold! '+10001,'hey! '
從上面的對比我們可以知道,內存表中如果使用了varchar類型,那么表創建的時候,會以varchar最大的長度來申請內存,這樣,如果我們如果設計長度不合理的時候,就會造成內存浪費。并且內存表不支持BLOB或TEXT類型,這個不支持的原因也可以理解了。內存表不支持事務,因為內存表是表鎖,所以當修改頻繁時會影響表的性能。
再者,是表大小的問題,內存表到底能有多大?理論上說,只要你內存足夠大,表就可以有多大,但是默認內存表默認的大小是64MB(如果我沒有記錯的話),如果我們要設置成自己想要的大小,我們需要在my.cnf文件中修改max_heap_table_size參數,修改完成后,要重啟MySQL才會生效。如果我們的表滿了以后,MySQL并不會把數據存儲到硬盤中,而是直接報表已經滿了的錯誤。
3.我們使用內存表的時候還需要注意些什么操作?
我之前用100GB的內存做了測試,建了35張表,其中有一張表插入了大概30GB左右的數據,其他34張表平均不到1GB的數據,然后我嘗試在30GB的表里面做了turncate操作,卡了一段時間之后,操作成功,但其他34張表也受到了影響,數據竟然全部不見了!于是我又繼續插入上次的數據,再對34張表中的其中任意一張表做turncate操作,這次竟然沒有影響,我猜測可能是內存占用過大的話,會有什么不可預料的事情發生吧,這一切發生在RHEL,具體什么原因也不太清楚了。
后來我嘗試使用delete、update語句可以正常使用,不過由于是表鎖機制,所以我們在實際使用過程中,也要注意操作表的先后順序,保證讀或者寫的時候,沒有其他連接操作把表鎖住了,不然你會發現你的操作會失敗,并且MySQL不會告訴你表已經鎖了,這個時候就只能靠自己的直覺去判斷是不是表鎖了。
來自:http://my.oschina.net/lanzp/blog/369179