不需要事務(wù)支持(不支持)
并發(fā)相對(duì)較低(鎖定機(jī)制問(wèn)題)
數(shù)據(jù)修改相對(duì)較少(阻塞問(wèn)題),以讀為主
數(shù)據(jù)一致性要求不是非常高
盡量索引(緩存機(jī)制)
調(diào)整讀寫(xiě)優(yōu)先級(jí),根據(jù)實(shí)際需求確保重要操作更優(yōu)先
啟用延遲插入改善大批量寫(xiě)入性能
盡量順序操作讓insert數(shù)據(jù)都寫(xiě)入到尾部,減少阻塞
分解大的操作,降低單個(gè)操作的阻塞時(shí)間
降低并發(fā)數(shù),某些高并發(fā)場(chǎng)景通過(guò)應(yīng)用來(lái)進(jìn)行排隊(duì)機(jī)制
對(duì)于相對(duì)靜態(tài)的數(shù)據(jù),充分利用Query Cache可以極大的提高訪問(wèn)效率
MyISAM的Count只有在全表掃描的時(shí)候特別高效,帶有其他條件的count都需要進(jìn)行實(shí)際的數(shù)據(jù)訪問(wèn)
需要事務(wù)支持(具有較好的事務(wù)特性)
行級(jí)鎖定對(duì)高并發(fā)有很好的適應(yīng)能力,但需要確保查詢是通過(guò)索引完成
數(shù)據(jù)更新較為頻繁的場(chǎng)景
數(shù)據(jù)一致性要求較高
硬件設(shè)備內(nèi)存較大,可以利用InnoDB較好的緩存能力來(lái)提高內(nèi)存利用率,盡可能減少磁盤(pán) IO
主鍵盡可能小,避免給Secondary index帶來(lái)過(guò)大的空間負(fù)擔(dān)
避免全表掃描,因?yàn)闀?huì)使用表鎖
盡可能緩存所有的索引和數(shù)據(jù),提高響應(yīng)速度
在大批量小插入的時(shí)候,盡量自己控制事務(wù)而不要使用autocommit自動(dòng)提交
合理設(shè)置innodb_flush_log_at_trx_commit參數(shù)值,不要過(guò)度追求安全性
避免主鍵更新,因?yàn)檫@會(huì)帶來(lái)大量的數(shù)據(jù)移動(dòng)
區(qū)別:
1. InnoDB 支持事務(wù),MyISAM 不支持事務(wù)。這是 MySQL 將默認(rèn)存儲(chǔ)引擎從 MyISAM 變成 InnoDB 的重要原因之一;
2. InnoDB 支持外鍵,而 MyISAM 不支持。對(duì)一個(gè)包含外鍵的 InnoDB 表轉(zhuǎn)為 MYISAM 會(huì)失?。?/p>
3. InnoDB 是聚集索引,MyISAM 是非聚集索引。聚簇索引的文件存放在主鍵索引的葉子節(jié)點(diǎn)上,因此 InnoDB 必須要有主鍵,通過(guò)主鍵索引效率很高。但是輔助索引需要兩次查詢,先查詢到主鍵,然后再通過(guò)主鍵查詢到數(shù)據(jù)。因此,主鍵不應(yīng)該過(guò)大,因?yàn)橹麈I太大,其他索引也都會(huì)很大。而 MyISAM 是非聚集索引,數(shù)據(jù)文件是分離的,索引保存的是數(shù)據(jù)文件的指針。主鍵索引和輔助索引是獨(dú)立的。
4. InnoDB 不保存表的具體行數(shù),執(zhí)行 select count(*) from table 時(shí)需要全表掃描。而MyISAM 用一個(gè)變量保存了整個(gè)表的行數(shù),執(zhí)行上述語(yǔ)句時(shí)只需要讀出該變量即可,速度很快;
5. InnoDB 最小的鎖粒度是行鎖,MyISAM 最小的鎖粒度是表鎖。一個(gè)更新語(yǔ)句會(huì)鎖住整張表,導(dǎo)致其他查詢和更新都會(huì)被阻塞,因此并發(fā)訪問(wèn)受限。這也是 MySQL 將默認(rèn)存儲(chǔ)引擎從 MyISAM 變成 InnoDB 的重要原因之一;
如何選擇:
1. 是否要支持事務(wù),如果要請(qǐng)選擇 InnoDB,如果不需要可以考慮 MyISAM;
2. 如果表中絕大多數(shù)都只是讀查詢,可以考慮 MyISAM,如果既有讀寫(xiě)也挺頻繁,請(qǐng)使用InnoDB。
3. 系統(tǒng)奔潰后,MyISAM恢復(fù)起來(lái)更困難,能否接受,不能接受就選 InnoDB;
4. MySQL5.5版本開(kāi)始Innodb已經(jīng)成為Mysql的默認(rèn)引擎(之前是MyISAM),說(shuō)明其優(yōu)勢(shì)是有目共睹的。如果你不知道用什么存儲(chǔ)引擎,那就用InnoDB,至少不會(huì)差。
MyISAM | InnoDB | |
構(gòu)成上的區(qū)別: | 每個(gè)MyISAM在磁盤(pán)上存儲(chǔ)成三個(gè)文件。第一個(gè)文件的名字以表的名字開(kāi)始,擴(kuò)展名指出文件類(lèi)型。 .frm文件存儲(chǔ)表定義。 數(shù)據(jù)文件的擴(kuò)展名為.MYD (MYData)。 索引文件的擴(kuò)展名是.MYI (MYIndex)。 | 基于磁盤(pán)的資源是InnoDB表空間數(shù)據(jù)文件和它的日志文件,InnoDB 表的大小只受限于操作系統(tǒng)文件的大小,一般為 2GB |
事務(wù)處理上方面: | MyISAM類(lèi)型的表強(qiáng)調(diào)的是性能,其執(zhí)行數(shù)度比InnoDB類(lèi)型更快,但是不提供事務(wù)支持 | InnoDB提供事務(wù)支持事務(wù),外部鍵(foreign key)等高級(jí)數(shù)據(jù)庫(kù)功能 |
SELECT UPDATE,INSERT,Delete操作 | 如果執(zhí)行大量的SELECT,MyISAM是更好的選擇 | 1.如果你的數(shù)據(jù)執(zhí)行大量的INSERT或UPDATE,出于性能方面的考慮,應(yīng)該使用InnoDB表 2.DELETE FROM table時(shí),InnoDB不會(huì)重新建立表,而是一行一行的刪除。 3.LOAD TABLE FROM MASTER操作對(duì)InnoDB是不起作用的,解決方法是首先把InnoDB表改成MyISAM表,導(dǎo)入數(shù)據(jù)后再改成InnoDB表,但是對(duì)于使用的額外的InnoDB特性(例如外鍵)的表不適用 |
對(duì)AUTO_INCREMENT的操作 | 每表一個(gè)AUTO_INCREMEN列的內(nèi)部處理。 MyISAM為INSERT和UPDATE操作自動(dòng)更新這一列。這使得AUTO_INCREMENT列更快(至少10%)。在序列頂?shù)闹当粍h除之后就不能再利用。(當(dāng)AUTO_INCREMENT列被定義為多列索引的最后一列,可以出現(xiàn)重使用從序列頂部刪除的值的情況)。 AUTO_INCREMENT值可用ALTER TABLE或myisamch來(lái)重置 對(duì)于AUTO_INCREMENT類(lèi)型的字段,InnoDB中必須包含只有該字段的索引,但是在MyISAM表中,可以和其他字段一起建立聯(lián)合索引 更好和更快的auto_increment處理 | 如果你為一個(gè)表指定AUTO_INCREMENT列,在數(shù)據(jù)詞典里的InnoDB表句柄包含一個(gè)名為自動(dòng)增長(zhǎng)計(jì)數(shù)器的計(jì)數(shù)器,它被用在為該列賦新值。 自動(dòng)增長(zhǎng)計(jì)數(shù)器僅被存儲(chǔ)在主內(nèi)存中,而不是存在磁盤(pán)上 關(guān)于該計(jì)算器的算法實(shí)現(xiàn),請(qǐng)參考 AUTO_INCREMENT列在InnoDB里如何工作 |
表的具體行數(shù) | select count(*) from table,MyISAM只要簡(jiǎn)單的讀出保存好的行數(shù),注意的是,當(dāng)count(*)語(yǔ)句包含 where條件時(shí),兩種表的操作是一樣的 | InnoDB 中不保存表的具體行數(shù),也就是說(shuō),執(zhí)行select count(*) from table時(shí),InnoDB要掃描一遍整個(gè)表來(lái)計(jì)算有多少行 |
鎖 | 表鎖 | 提供行鎖(locking on row level),提供與 Oracle 類(lèi)型一致的不加鎖讀取(non-locking read in SELECTs),另外,InnoDB表的行鎖也不是絕對(duì)的,如果在執(zhí)行一個(gè)SQL語(yǔ)句時(shí)MySQL不能確定要掃描的范圍,InnoDB表同樣會(huì)鎖全表, 例如update table set num=1 where name like "%aaa%" |
雖然 MySQL 里的存儲(chǔ)引擎不只是 MyISAM 與 InnoDB 這兩個(gè),但常用的就是它倆了。可能有站長(zhǎng)并未注意過(guò) MySQL 的存儲(chǔ)引擎,其實(shí)存儲(chǔ)引擎也是數(shù)據(jù)庫(kù)設(shè)計(jì)里的一大重要點(diǎn),那么博客系統(tǒng)應(yīng)該使用哪種存儲(chǔ)引擎呢?
下面我們分別來(lái)看兩種存儲(chǔ)引擎的區(qū)別。
一、InnoDB支持事務(wù),MyISAM不支持,這一點(diǎn)是非常之重要。事務(wù)是一種高級(jí)的處理方式,如在一些列增刪改中只要哪個(gè)出錯(cuò)還可以回滾還原,而MyISAM就不可以了。
二、MyISAM適合查詢以及插入為主的應(yīng)用,InnoDB適合頻繁修改以及涉及到安全性較高的應(yīng)用
三、InnoDB支持外鍵,MyISAM不支持
四、MyISAM是默認(rèn)引擎,InnoDB需要指定
五、InnoDB不支持FULLTEXT類(lèi)型的索引
六、InnoDB中不保存表的行數(shù),如select count(*) from table時(shí),InnoDB需要掃描一遍整個(gè)表來(lái)計(jì)算有多少行,但是MyISAM只要簡(jiǎn)單的讀出保存好的行數(shù)即可。注意的是,當(dāng)count(*)語(yǔ)句包含where條件時(shí)MyISAM也需要掃描整個(gè)表
七、對(duì)于自增長(zhǎng)的字段,InnoDB中必須包含只有該字段的索引,但是在MyISAM表中可以和其他字段一起建立聯(lián)合索引
八、清空整個(gè)表時(shí),InnoDB是一行一行的刪除,效率非常慢。MyISAM則會(huì)重建表
九、InnoDB支持行鎖(某些情況下還是鎖整表,如 update table set a=1 where user like '%lee%'
通過(guò)以上九點(diǎn)區(qū)別,結(jié)合個(gè)人博客的特點(diǎn),推薦個(gè)人博客系統(tǒng)使用MyISAM,因?yàn)樵诓┛屠镏饕僮魇亲x取和寫(xiě)入,很少有鏈?zhǔn)讲僮?。所以選擇MyISAM引擎使你博客打開(kāi)也頁(yè)面的效率要高于InnoDB引擎的博客,當(dāng)然只是個(gè)人的建議,大多數(shù)博客還是根據(jù)實(shí)際情況下謹(jǐn)慎選擇。
一些關(guān)于MyISAM與InnoDB選擇使用:
MYISAM和INNODB是Mysql數(shù)據(jù)庫(kù)提供的兩種存儲(chǔ)引擎。兩者的優(yōu)劣可謂是各有千秋。INNODB會(huì)支持一些關(guān)系數(shù)據(jù)庫(kù)的高級(jí)功能,如事務(wù)功能和行級(jí)鎖,MYISAM不支持。MYISAM的性能更優(yōu),占用的存儲(chǔ)空間少。所以,選擇何種存儲(chǔ)引擎,視具體應(yīng)用而定。
如果你的應(yīng)用程序一定要使用事務(wù),毫無(wú)疑問(wèn)你要選擇INNODB引擎。但要注意,INNODB的行級(jí)鎖是有條件的。在where條件沒(méi)有使用主鍵時(shí),照樣會(huì)鎖全表。比如DELETE FROM mytable這樣的刪除語(yǔ)句。
如果你的應(yīng)用程序?qū)Σ樵冃阅芤筝^高,就要使用MYISAM了。MYISAM索引和數(shù)據(jù)是分開(kāi)的,而且其索引是壓縮的,可以更好地利用內(nèi)存。所以它的查詢性能明顯優(yōu)于INNODB。壓縮后的索引也能節(jié)約一些磁盤(pán)空間。MYISAM擁有全文索引的功能,這可以極大地優(yōu)化LIKE查詢的效率。
有人說(shuō)MYISAM只能用于小型應(yīng)用,其實(shí)這只是一種偏見(jiàn)。如果數(shù)據(jù)量比較大,這是需要通過(guò)升級(jí)架構(gòu)來(lái)解決,比如分表分庫(kù),而不是單純地依賴(lài)存儲(chǔ)引擎。
其他一些說(shuō)法:
現(xiàn)在一般都是選用innodb了,主要是myisam的全表鎖,讀寫(xiě)串行問(wèn)題,并發(fā)效率鎖表,效率低myisam對(duì)于讀寫(xiě)密集型應(yīng)用一般是不會(huì)去選用的。
關(guān)于Mysql數(shù)據(jù)庫(kù)默認(rèn)的存儲(chǔ)引擎:
MyISAM和InnoDB是MySQL的兩種存儲(chǔ)引擎。如果是默認(rèn)安裝,那就應(yīng)該是InnoDB,你可以在my.ini文件中找到default-storage-engine=INNODB;當(dāng)然你可以在建表時(shí)指定相應(yīng)的存儲(chǔ)引擎。通過(guò)show create table xx 可以看見(jiàn)相應(yīng)信息。
MyISAM:
每個(gè)MyISAM在磁盤(pán)上存儲(chǔ)成三個(gè)文件。第一個(gè)文件的名字以表的名字開(kāi)始,擴(kuò)展名指出文件類(lèi)型。.frm文件存儲(chǔ)表定義。數(shù)據(jù)文件的擴(kuò)展名為.MYD (MYData)。
MyISAM表格可以被壓縮,而且它們支持全文搜索。不支持事務(wù),而且也不支持外鍵。如果事物回滾將造成不完全回滾,不具有原子性。在進(jìn)行updata時(shí)進(jìn)行表鎖,并發(fā)量相對(duì)較小。如果執(zhí)行大量的SELECT,MyISAM是更好的選擇。
MyISAM的索引和數(shù)據(jù)是分開(kāi)的,并且索引是有壓縮的,內(nèi)存使用率就對(duì)應(yīng)提高了不少。能加載更多索引,而Innodb是索引和數(shù)據(jù)是緊密捆綁的,沒(méi)有使用壓縮從而會(huì)造成Innodb比MyISAM體積龐大不小
MyISAM緩存在內(nèi)存的是索引,不是數(shù)據(jù)。而InnoDB緩存在內(nèi)存的是數(shù)據(jù),相對(duì)來(lái)說(shuō),服務(wù)器內(nèi)存越大,InnoDB發(fā)揮的優(yōu)勢(shì)越大。
優(yōu)點(diǎn):查詢數(shù)據(jù)相對(duì)較快,適合大量的select,可以全文索引。
缺點(diǎn):不支持事務(wù),不支持外鍵,并發(fā)量較小,不適合大量update
InnoDB:
這種類(lèi)型是事務(wù)安全的。.它與BDB類(lèi)型具有相同的特性,它們還支持外鍵。InnoDB表格速度很快。具有比BDB還豐富的特性,因此如果需要一個(gè)事務(wù)安全的存儲(chǔ)引擎,建議使用它。在update時(shí)表進(jìn)行行鎖,并發(fā)量相對(duì)較大。如果你的數(shù)據(jù)執(zhí)行大量的INSERT或UPDATE,出于性能方面的考慮,應(yīng)該使用InnoDB表。
優(yōu)點(diǎn):支持事務(wù),支持外鍵,并發(fā)量較大,適合大量update
缺點(diǎn):查詢數(shù)據(jù)相對(duì)較快,不適合大量的select
對(duì)于支持事物的InnoDB類(lèi)型的表,影響速度的主要原因是AUTOCOMMIT默認(rèn)設(shè)置是打開(kāi)的,而且程序沒(méi)有顯式調(diào)用BEGIN 開(kāi)始事務(wù),導(dǎo)致每插入一條都自動(dòng)Commit,嚴(yán)重影響了速度??梢栽趫?zhí)行sql前調(diào)用begin,多條sql形成一個(gè)事物(即使autocommit打開(kāi)也可以),將大大提高性能。
基本的差別為:MyISAM類(lèi)型不支持事務(wù)處理等高級(jí)處理,而InnoDB類(lèi)型支持。
MyISAM類(lèi)型的表強(qiáng)調(diào)的是性能,其執(zhí)行數(shù)度比InnoDB類(lèi)型更快,但是不提供事務(wù)支持,而InnoDB提供事務(wù)支持已經(jīng)外部鍵等高級(jí)數(shù)據(jù)庫(kù)功能。
其他比較:
MyIASM是IASM表的新版本,有如下擴(kuò)展:
二進(jìn)制層次的可移植性。
NULL列索引。
對(duì)變長(zhǎng)行比ISAM表有更少的碎片。
支持大文件。
更好的索引壓縮。
更好的鍵嗎統(tǒng)計(jì)分布。
更好和更快的auto_increment處理。
以下是一些細(xì)節(jié)和具體實(shí)現(xiàn)的差別:
1.InnoDB不支持FULLTEXT類(lèi)型的索引。
2.InnoDB 中不保存表的具體行數(shù),也就是說(shuō),執(zhí)行select count(*) from table時(shí),InnoDB要掃描一遍整個(gè)表來(lái)計(jì)算有多少行,但是MyISAM只要簡(jiǎn)單的讀出保存好的行數(shù) 即可。注意的是,當(dāng)count(*)語(yǔ)句包含 where條件時(shí),兩種表的操作是一樣的。
3.對(duì)于AUTO_INCREMENT類(lèi)型的字段,InnoDB中必須包含只有該字段的索引,但是在MyISAM表中,可以和其他字段一起建立聯(lián)合索引。
4.DELETE FROM table時(shí),InnoDB不會(huì)重新建立表,而是一行一行的刪除。
5.LOAD TABLE FROM MASTER操作對(duì)InnoDB是不起作用的,解決方法是首先把InnoDB表改成MyISAM表,導(dǎo)入數(shù)據(jù)后再改成InnoDB表,但是對(duì)于使用的額外的 InnoDB特性(例如外鍵)的表不適用。
另外,InnoDB表的行鎖也不是絕對(duì)的,如果在執(zhí)行一個(gè)SQL語(yǔ)句時(shí)MySQL不能確定要掃描的范圍,InnoDB表同樣會(huì)鎖全表,例如update table set num=1 where name like "%aaa%"
任何一種表都不是萬(wàn)能的,只用恰當(dāng)?shù)尼槍?duì)業(yè)務(wù)類(lèi)型來(lái)選擇合適的表類(lèi)型,才能最大的發(fā)揮MySQL的性能優(yōu)勢(shì)。
innodb和myisam更新比較:
innodb的數(shù)據(jù)組織就是按照主鍵建成的一個(gè)B+樹(shù),如果沒(méi)有顯示的定義主鍵,那么innodb會(huì)選區(qū)一個(gè)not null unique key,作為主鍵,如果還是沒(méi)有,那么innodb會(huì)創(chuàng)建一個(gè) 6字節(jié)的主鍵,主鍵索引到頁(yè)不是具體的行位置
不是遞增的主鍵會(huì)使得插入的速度很慢,例如使用手機(jī)號(hào)或身份證號(hào)做為主鍵,所以善用AUTO_INCREMENT
表大不可怕,可怕的是count或者高偏移limit,可以將大的limit big換成 limit max_id, xxxxx
Limit 0 1000 | limit 1001 1000 | limit 2001 1000Limit 0 1000 | where id>max_id1 limit 1000 | where id>max_id2 limit 1000
對(duì)于InnoDB來(lái)說(shuō),按照某列分表,想在單臺(tái)服務(wù)器上提高性能是沒(méi)有意義的
插入的速度和查詢的速度有時(shí)候是不可調(diào)和的矛盾
說(shuō)InnoDB不適合做count是不對(duì)的,MyISAM也是一樣的慢,只不過(guò)MyISAM將正表的行數(shù)緩存起來(lái),所以count整表很快,如果有查詢條件,并且不是主鍵查詢,那就沒(méi)有什么區(qū)別,主鍵count慢的原因是innodb是按照主鍵組織的,按照主鍵count的時(shí)候,會(huì)加載數(shù)據(jù)
InnoDB的頁(yè)式存儲(chǔ)會(huì)使得InnoDB更容易做整表緩存和熱備份
如果表索引很多,那么InnoDB的更新速度要大于MyISAM,因?yàn)镮nnoDB的輔助索引關(guān)聯(lián)的是表的主鍵,是一個(gè)邏輯的值,而MyISAM的所有索引關(guān)聯(lián)的是數(shù)據(jù)的物理位置,更新時(shí)有可能數(shù)據(jù)的物理位置發(fā)生變化,如果發(fā)生變化,那么所有的索引都要做更新
InnoDB 中不保存表的具體行數(shù),也就是說(shuō),執(zhí)行select count(*) from table時(shí),InnoDB要掃描一遍整個(gè)表來(lái)計(jì)算有多少行,但是MyISAM只要簡(jiǎn)單的讀出保存好的行數(shù)即可。注意的是,當(dāng)count(*)語(yǔ)句包含 where條件時(shí),兩種表的操作是一樣的。
如對(duì)本文有疑問(wèn),請(qǐng)?zhí)峤坏浇涣髡搲?,廣大熱心網(wǎng)友會(huì)為你解答!! 點(diǎn)擊進(jìn)入論壇