mysql - 内存表使用总结
部分轉(zhuǎn)載:https://blog.csdn.net/hemeinvyiqiluoben/article/details/51222951?utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control&dist_request_id=&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control
http://my.oschina.net/lanzp/blog/369179
內(nèi)存表使用哈希散列索引把數(shù)據(jù)保存在內(nèi)存中,因此具有極快的速度,適合緩存中小型數(shù)據(jù)庫,但是使用上受到一些限制
定義:
create table (...)? engine = memory/heap ;? (一般使用memory,heap用得少了)
用法:
①、內(nèi)存表的數(shù)據(jù)是使用hash的方式存儲在內(nèi)存上,故其查詢的時候只支持 <> 和 = 這兩種比較方式;
②、內(nèi)存表的數(shù)據(jù)可以對所有用戶的連接可見,但是其不能跨服務(wù)器重啟; 服務(wù)器重啟后,內(nèi)存表中的所有數(shù)據(jù)都將丟失,但是表結(jié)構(gòu)還在,因為表結(jié)構(gòu)是存儲在磁盤中;
③、內(nèi)存表的數(shù)據(jù)在max_heap_table_size這里設(shè)定,若單張表行數(shù)超過了這個長度,則報數(shù)據(jù)滿錯誤 ; 我電腦里的mysql本參數(shù)默認(rèn)值是16777216 ;
④、內(nèi)存表不支持事務(wù),而且是表鎖,當(dāng)修改頻繁時,性能會下降
⑤、內(nèi)存表使用一個固定的記錄長度格式,一般來說不要用varchar類型,如果使用了它會以varchar的最大長度來申請內(nèi)存。內(nèi)存表不支持BLOB或TEXT類型
⑥、內(nèi)存表不支持auto_increment <我的新版的mysql測試時支持 自增列的>;只允許對非空數(shù)據(jù)列進(jìn)行索引(not null)
⑦、如果heap是復(fù)制的某數(shù)據(jù)表,則復(fù)制之后所有主鍵、索引、自增等格式將不復(fù)存在,需要重新添加主鍵和索引,如果需要的話。
首先,我們來說一下什么是內(nèi)存表,所謂內(nèi)存表,是指整個數(shù)據(jù)庫表都常駐在內(nèi)存中的表,相對于普通表而言,內(nèi)存表存儲數(shù)據(jù)在內(nèi)存中,而普通表存儲在硬盤中。那么內(nèi)存表到底有什么特點呢?下面我們來詳細(xì)地分析一下。
1.MySQL內(nèi)存表要怎樣創(chuàng)建呢?
?首先,我們先來學(xué)習(xí)一下到底要怎樣創(chuàng)建一個內(nèi)存表呢?方法很簡單,就跟普通表差不多,唯一的差異是,內(nèi)存表所使用的數(shù)據(jù)庫引擎是內(nèi)存。如下:
?
?
我們普通表的引擎一般是InnoDB,我們要使用內(nèi)存表,就必須把引擎設(shè)置成MEMORY。內(nèi)存表的結(jié)構(gòu)存放在磁盤上,擴展名為.frm, 所以重啟不會丟失。但是數(shù)據(jù)是存儲在內(nèi)存當(dāng)中,所以重啟之后,表數(shù)據(jù)會全部丟失。
2.MySQL內(nèi)存表到底有什么限制?
? 如果你平時設(shè)計數(shù)據(jù)庫表的時候,有喜歡使用varchar類型的習(xí)慣的話,那么,你使用內(nèi)存表的時候,就需要注意到一個細(xì)節(jié)了。我們都知道,在使用內(nèi)存之前,都要先申請一段內(nèi)存,那么也就是說,內(nèi)存表在創(chuàng)建之后,每一行要使用的內(nèi)存就已經(jīng)固定下來了,但是我們都知道,varchar類型是動態(tài)可變長度,只有一個上限值,那么內(nèi)存表會怎么做呢,先看下面一個例子:
以上面的表為例,假如有這么兩條記錄:
10000,'greatWall!' ?
10001,'qq!'
普通表占用空間 -> 10000,'greatWall!'+10001,'qq!'
內(nèi)存表占用空間 -> 10000,'greatWall!??? '+10001,'qq!????????? '
從上面的對比我們可以知道,內(nèi)存表中如果使用了varchar類型,那么表創(chuàng)建的時候,會以varchar最大的長度來申請內(nèi)存,這樣,如果我們?nèi)绻O(shè)計長度不合理的時候,就會造成內(nèi)存浪費。并且內(nèi)存表不支持BLOB或TEXT類型,這個不支持的原因也可以理解了。內(nèi)存表不支持事務(wù),因為內(nèi)存表是表鎖,所以當(dāng)修改頻繁時會影響表的性能。
再者,是表大小的問題,內(nèi)存表到底能有多大?理論上說,只要你內(nèi)存足夠大,表就可以有多大,但是默認(rèn)內(nèi)存表默認(rèn)的大小是64MB(如果我沒有記錯的話),如果我們要設(shè)置成自己想要的大小,我們需要在my.cnf文件中修改max_heap_table_size參數(shù),修改完成后,要重啟MySQL才會生效。如果我們的表滿了以后,MySQL并不會把數(shù)據(jù)存儲到硬盤中,而是直接報表已經(jīng)滿了的錯誤。
3.我們使用內(nèi)存表的時候還需要注意些什么操作?
? 我之前用100GB的內(nèi)存做了測試,建了35張表,其中有一張表插入了大概30GB左右的數(shù)據(jù),其他34張表平均不到1GB的數(shù)據(jù),然后我嘗試在30GB的表里面做了turncate操作,卡了一段時間之后,操作成功,但其他34張表也受到了影響,數(shù)據(jù)竟然全部不見了!于是我又繼續(xù)插入上次的數(shù)據(jù),再對34張表中的其中任意一張表做turncate操作,這次竟然沒有影響,我猜測可能是內(nèi)存占用過大的話,會有什么不可預(yù)料的事情發(fā)生吧,這一切發(fā)生在RHEL,具體什么原因也不太清楚了。
?后來我嘗試使用delete、update語句可以正常使用,不過由于是表鎖機制,所以我們在實際使用過程中,也要注意操作表的先后順序,保證讀或者寫的時候,沒有其他連接操作把表鎖住了,不然你會發(fā)現(xiàn)你的操作會失敗,并且MySQL不會告訴你表已經(jīng)鎖了,這個時候就只能靠自己的直覺去判斷是不是表鎖了。
————————————————
?
總結(jié)
以上是生活随笔為你收集整理的mysql - 内存表使用总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 反馈电路中相位补偿,到底是什么鬼?
- 下一篇: mysql 8.0 一条insert语句