我用MySQL的時候用的是Navicat for MySQL(Navicat for mysql v9.0.15註冊碼生成器)操做庫、表操做的,默認的表就是InnoDB類型,也就沒有在乎。最近作項目時發現表裏除了有InnoDB類型外還有MyISAM類型,上官網看了看以後作如下總結:html
原來是MyISAM類型不支持事務處理等高級處理,而InnoDB類型支持。 MyISAM類型的表強調的是性能,其執行數度比InnoDB類型更快,可是不提供事務支持,而InnoDB提供事務支持已經外部鍵等高級數據庫功能。綜述,就能夠根據數據表不一樣的用處是用不一樣的存儲類型。並且MyISAM是文件存儲的,能夠進行直接在不一樣操做系統間拷貝使用。mysql
InnoDB:sql
InnoDB 給 MySQL 提供了具備事務(commit)、回滾(rollback)和崩潰修復能力(crash recovery capabilities)的事務安全(transaction-safe (ACID compliant))型表。InnoDB 提供了行鎖(locking on row level),提供與 Oracle 類型一致的不加鎖讀取(non-locking read in SELECTs)。這些特性均提升了多用戶併發操做的性能表現。在InnoDB表中不須要擴大鎖定(lock escalation),由於 InnoDB 的列鎖定(row level locks)適宜很是小的空間。InnoDB 是 MySQL 上第一個提供外鍵約束(FOREIGN KEY constraints)的表引擎。InnoDB 的設計目標是處理大容量數據庫系統,它的 CPU 利用率是其它基於磁盤的關係數據庫引擎所不能比的。在技術上,InnoDB 是一套放在 MySQL 後臺的完整數據庫系統,InnoDB 在主內存中創建其專用的緩衝池用於高速緩衝數據和索引。 InnoDB 把數據和索引存放在表空間裏,可能包含多個文件,這與其它的不同,舉例來講,在 MyISAM 中,表被存放在單獨的文件中。InnoDB 表的大小隻受限於操做系統的文件大小,通常爲 2 GB。InnoDB全部的表都保存在同一個數據文件 ibdata1 中(也多是多個文件,或者是獨立的表空間文件),相對來講比較很差備份,能夠拷貝文件或用navicat for mysql。數據庫
MyISAM緩存
每張MyISAM 表被存放在三個文件 :frm 文件存放表格定義。 數據文件是MYD (MYData) 。 索引文件是MYI (MYIndex) 引申。
由於MyISAM相對簡單因此在效率上要優於InnoDB,小型應用使用MyISAM是不錯的選擇。
MyISAM表是保存成文件的形式,在跨平臺的數據轉移中使用MyISAM存儲會省去很多的麻煩安全
MyISAM 和InnoDB 講解服務器
InnoDB和MyISAM是許多人在使用MySQL時最經常使用的兩個表類型,這兩個表類型各有優劣,視具體應用而定。基本的差異爲:MyISAM類型不支持事務處理等高級處理,而InnoDB類型支持。MyISAM類型的表強調的是性能,其執行數度比InnoDB類型更快,可是不提供事務支持,而InnoDB提供事務支持以及外部鍵等高級數據庫功能。多線程
如下是一些細節和具體實現的差異:架構
◆1.InnoDB不支持FULLTEXT類型的索引。併發
◆2.InnoDB 中不保存表的具體行數,也就是說,執行select count(*) from table時,InnoDB要掃描一遍整個表來計算有多少行,可是MyISAM只要簡單的讀出保存好的行數便可。注意的是,當count(*)語句包含 where條件時,兩種表的操做是同樣的。
◆3.對於AUTO_INCREMENT類型的字段,InnoDB中必須包含只有該字段的索引,可是在MyISAM表中,能夠和其餘字段一塊兒創建聯合索引。
◆4.DELETE FROM table時,InnoDB不會從新創建表,而是一行一行的刪除。
◆5.LOAD TABLE FROM MASTER操做對InnoDB是不起做用的,解決方法是首先把InnoDB表改爲MyISAM表,導入數據後再改爲InnoDB表,可是對於使用的額外的InnoDB特性(例如外鍵)的表不適用。
一、MyISAM不支持事務,InnoDB是事務類型的存儲引擎
當咱們的表須要用到事務支持的時候,那確定是不能選擇MyISAM了。
二、MyISAM只支持表級鎖,BDB支持頁級鎖和表級鎖默認爲頁級鎖,而InnoDB支持行級鎖和表級鎖默認爲行級鎖
表級鎖:直接鎖定整張表,在鎖按期間,其餘進程沒法對該表進行寫操做,若是設置的是寫鎖,那麼其餘進程讀也不容許
MyISAM是表級鎖定的存儲引擎,它不會出現死鎖問題
對於write,表鎖定原理以下:
若是表上沒有鎖,在其上面放置一個寫鎖,不然,把鎖定請求放在寫鎖隊列中。
對於read,表鎖定原理以下 :
若是表上沒有寫鎖定,那麼把一個讀鎖放在其上面,不然把鎖請求放在讀鎖定隊列中
當一個鎖定被釋放時,表可被寫鎖定隊列中的線程獲得,而後纔是讀鎖定隊列中的線程。這意味着,若是你在一個表上有許多更新,那麼你的SELECT語句將等到全部的寫鎖定
線程執行完。
行級鎖:只對指定的行進行鎖定,其餘進程仍是能夠對錶中的其餘行進行操做的。
行級鎖是Mysql粒度最小的一種鎖,它能大大的減小數據庫操做的衝突,可是粒度越小實現成本也越大。
行級鎖可能會致使「死鎖」,那究竟是怎麼致使的呢,分析緣由:Mysql行級鎖並非直接鎖記錄,而是鎖索引。索引分爲主鍵索引和非主鍵索引兩種,若是一條sql語句操做了主
鍵索引,那麼Mysql就會鎖定這個主鍵索引,若是sql語句操做的是非主鍵索引,那麼Mysql會先鎖定這個非主鍵索引,再去鎖定主鍵索引。
在UPDATE 和 DELETE操做時Mysql不只會鎖定全部WHERE 條件掃描過得索引,還會鎖定相鄰的鍵值。
「死鎖」舉例分析:
表Test:(ID,STATE,TIME) 主鍵索引:ID 非主鍵索引:STATE
當執行"UPDATE STATE =1011 WHERE STATE=1000" 語句的時候會鎖定STATE索引,因爲STATE 是非主鍵索引,因此Mysql還會去請求鎖定ID索引
當另外一個SQL語句與語句1幾乎同時執行時:「UPDATE STATE=1010 WHERE ID=1」 對於語句2 Mysql會先鎖定ID索引,因爲語句2操做了STATE字段,因此Mysql還會請求鎖
定STATE索引。這時。彼此鎖定着對方須要的索引,又都在等待對方釋放鎖定。因此出現了"死鎖"的狀況。
行級鎖的優勢:
有許多線程訪問不一樣的行時,只存在少許的衝突。
回滾時只有少許的更改
能夠長時間鎖定單一的行
行級鎖缺點:
相對於頁級鎖和表級鎖來講佔用了更多的內存
當表的大部分行在使用時,比頁級鎖和表級鎖慢,由於你必須得到更多的鎖
當在大部分數據上常用GROUP BY操做,確定會比表級鎖和頁級鎖慢。
頁級鎖:表級鎖速度快,可是衝突多;行級鎖速度慢,但衝突少;頁級鎖就是他倆折中的,一次鎖定相鄰的一組記錄。
三、MyISAM引擎不支持外鍵,InnoDB支持外鍵
四、MyISAM引擎的表在大量高併發的讀寫下會常常出現表損壞的狀況
咱們正在作的項目就遇到這個問題,表的INSERT 和 UPDATE操做很頻繁,原來用的MyISAM引擎,致使表隔三差五就損壞,後來更換成了InnoDB引擎。
其餘容易致使表損壞緣由:
服務器忽然斷電致使數據文件損壞,強制關機(mysqld未關閉狀況下)致使表損壞
mysqld進程在寫入操做的時候被殺掉
磁盤故障
表損壞常見症狀:
查詢表不能返回數據或返回部分數據
打開表失敗: Can’t open file: ‘×××.MYI’ (errno: 145) 。
Error: Table 'p' is marked as crashed and should be repaired 。
Incorrect key file for table: '...'. Try to repair it
Mysql表的恢復:
對於MyISAM表的恢復:
可使用Mysql自帶的myisamchk工具: myisamchk -r tablename 或者 myisamchk -o tablename(比前面的更保險) 對錶進行修復
五、對於count()查詢來講MyISAM更有優點七、MyISAM支持全文索引(FULLTEXT),InnoDB不支持
八、MyISAM引擎的表的查詢、更新、插入的效率要比InnoDB高
我沒有作過詳細的測試,就在網上截取了前輩們測試結論:
全部的性能測試在:Micrisoft window xp sp2 , Intel(R) Pentinum(R) M processor 1.6oGHz 1G 內存的電腦上測試。
測試方法:連續提交10個query, 表記錄總數:38萬 , 時間單位 s
引擎類型 MyISAM InnoDB 性能相差
count 0.0008357 3.0163 3609
查詢主鍵 0.005708 0.1574 27.57
查詢非主鍵 24.01 80.37 3.348
更新主鍵 0.008124 0.8183 100.7
更新非主鍵 0.004141 0.02625 6.338
插入 0.004188 0.3694 88.21
(1)加了索引之後,對於MyISAM查詢能夠加快:4 206.09733倍,對InnoDB查詢加快510.72921倍,同時對MyISAM更新速度減慢爲原來的1/2,InnoDB的更 新速度減慢爲原來的1/30。要看狀況決定是否要加索引,好比不查詢的log表,不要作任何的索引。
(2)若是你的數據量是百萬級別的,而且沒有任何的事務處理,那麼用MyISAM是性能最好的選擇。
(3)InnoDB表的大小更加的大,用MyISAM可省不少的硬盤空間。
在咱們測試的這個38w的表中,表佔用空間的狀況以下:
引擎類型 MyISAM InnoDB
數據 53,924 KB 58,976 KB
索引 13,640 KB 21,072 KB
佔用總空間 67,564 KB 80,048 KB
另一個176W萬記錄的表, 表佔用空間的狀況以下:
引擎類型 MyIsam InnorDB
數據 56,166 KB 90,736 KB
索引 67,103 KB 88,848 KB
佔用總空間 123,269 KB 179,584 KB
另外,InnoDB表的行鎖也不是絕對的,假如在執行一個SQL語句時MySQL不能肯定要掃描的範圍,InnoDB表一樣會鎖全表,例如update table set num=1 where name like 「%aaa%」
兩種類型最主要的差異就是Innodb 支持事務處理與外鍵和行級鎖。而MyISAM不支持.因此MyISAM每每就容易被人認爲只適合在小項目中使用。
做爲使用MySQL的用戶角度出發,Innodb和MyISAM都是比較喜歡的,若是數據庫平臺要達到需求:99.9%的穩定性,方便的擴展性和高可用性來講的話,MyISAM絕對是首選。
緣由以下:
一、平臺上承載的大部分項目是讀多寫少的項目,而MyISAM的讀性能是比Innodb強很多的。
二、MyISAM的索引和數據是分開的,而且索引是有壓縮的,內存使用率就對應提升了很多。能加載更多索引,而Innodb是索引和數據是緊密捆綁的,沒有使用壓縮從而會形成Innodb比MyISAM體積龐大不小。
三、常常隔1,2個月就會發生應用開發人員不當心update一個表where寫的範圍不對,致使這個表無法正經常使用了,這個時候MyISAM的優越性就體現出來了,隨便從當天拷貝的壓縮包取出對應表的文件,隨便放到一個數據庫目錄下,而後dump成sql再導回到主庫,並把對應的binlog補上。若是是Innodb,恐怕不可能有這麼快速度,別和我說讓Innodb按期用導出xxx.sql機制備份,由於最小的一個數據庫實例的數據量基本都是幾十G大小。
四、從接觸的應用邏輯來講,select count(*) 和order by 是最頻繁的,大概能佔了整個sql總語句的60%以上的操做,而這種操做Innodb其實也是會鎖表的,不少人覺得Innodb是行級鎖,那個只是where對它主鍵是有效,非主鍵的都會鎖全表的。
五、還有就是常常有不少應用部門須要我給他們按期某些表的數據,MyISAM的話很方便,只要發給他們對應那表的frm.MYD,MYI的文件,讓他們本身在對應版本的數據庫啓動就行,而Innodb就須要導出xxx.sql了,由於光給別人文件,受字典數據文件的影響,對方是沒法使用的。
六、若是和MyISAM比insert寫操做的話,Innodb還達不到MyISAM的寫性能,若是是針對基於索引的update操做,雖然MyISAM可能會遜色Innodb,可是那麼高併發的寫,從庫可否追的上也是一個問題,還不如經過多實例分庫分表架構來解決。
七、若是是用MyISAM的話,merge引擎能夠大大加快應用部門的開發速度,他們只要對這個merge表作一些select count(*)操做,很是適合大項目總量約幾億的rows某一類型(如日誌,調查統計)的業務表。
固然Innodb也不是絕對不用,用事務的項目就用Innodb的。另外,可能有人會說你MyISAM沒法抗太多寫操做,可是能夠經過架構來彌補。
兩種類型最主要的差異就是Innodb 支持事務處理與外鍵和行級鎖.而MyISAM不支持.因此MyISAM每每就容易被人認爲只適合在小項目中使用。
我做爲使用MySQL的用戶角度出發,Innodb和MyISAM都是比較喜歡的,可是從我目前運維的數據庫平臺要達到需求:99.9%的穩定性,方便的擴展性和高可用性來講的話,MyISAM絕對是個人首選。
緣由以下:
一、首先我目前平臺上承載的大部分項目是讀多寫少的項目,而MyISAM的讀性能是比Innodb強很多的。
二、MyISAM的索引和數據是分開的,而且索引是有壓縮的,內存使用率就對應提升了很多。能加載更多索引,而Innodb是索引和數據是緊密捆綁的,沒有使用壓縮從而會形成Innodb比MyISAM體積龐大不小。
三、從平臺角度來講,常常隔1,2個月就會發生應用開發人員不當心update一個表where寫的範圍不對,致使這個表無法正經常使用了,這個時候MyISAM的優越性就體現出來了,隨便從當天拷貝的壓縮包取出對應表的文件,隨便放到一個數據庫目錄下,而後dump成sql再導回到主庫,並把對應的binlog補上。若是是Innodb,恐怕不可能有這麼快速度,別和我說讓Innodb按期用導出xxx.sql機制備份,由於我平臺上最小的一個數據庫實例的數據量基本都是幾十G大小。
四、從我接觸的應用邏輯來講,select count(*) 和order by 是最頻繁的,大概能佔了整個sql總語句的60%以上的操做,而這種操做Innodb其實也是會鎖表的,不少人覺得Innodb是行級鎖,那個只是where對它主鍵是有效,非主鍵的都會鎖全表的。
五、還有就是常常有不少應用部門須要我給他們按期某些表的數據,MyISAM的話很方便,只要發給他們對應那表的frm.MYD,MYI的文件,讓他們本身在對應版本的數據庫啓動就行,而Innodb就須要導出xxx.sql了,由於光給別人文件,受字典數據文件的影響,對方是沒法使用的。
六、若是和MyISAM比insert寫操做的話,Innodb還達不到MyISAM的寫性能,若是是針對基於索引的update操做,雖然MyISAM可能會遜色Innodb,可是那麼高併發的寫,從庫可否追的上也是一個問題,還不如經過多實例分庫分表架構來解決。
七、若是是用MyISAM的話,merge引擎能夠大大加快應用部門的開發速度,他們只要對這個merge表作一些select count(*)操做,很是適合大項目總量約幾億的rows某一類型(如日誌,調查統計)的業務表。
固然Innodb也不是絕對不用,用事務的項目如模擬炒股項目,我就是用Innodb的,活躍用戶20多萬時候,也是很輕鬆應付了,所以我我的也是很喜歡Innodb的,只是若是從數據庫平臺應用出發,我仍是會首選MyISAM。
另外,可能有人會說你MyISAM沒法抗太多寫操做,可是我能夠經過架構來彌補,說個我現有用的數據庫平臺容量:主從數據總量在幾百T以上,天天十多億 pv的動態頁面,還有幾個大項目是經過數據接口方式調用未算進pv總數,(其中包括一個大項目由於初期memcached沒部署,致使單臺數據庫天天處理 9千萬的查詢)。而個人總體數據庫服務器平均負載都在0.5-1左右。
所謂事務處理,就是原子性操做。
打個比方,支持事務處理的Innodb表,建設一箇中,發帖是給積分的。你發了一個帖子執行一個insert語句,來插入帖子內容,插入後就要執行一個update語句來增長你的積分。假設一種特殊狀況忽然發生,insert成功了,update操做卻沒有被執行。也就是說你發了帖子卻沒有增長相應的積分。這就會形成用戶不滿。若是使用了事務處理,insert和update都放入到事務中去執行,這個時候,只有當insert和update兩條語句都執行生成的時候纔會將數據更新、寫入到中,若是其中任何一條語句失敗,那麼就會回滾爲初始狀態,不執行寫入。這樣就保證了insert和update確定是一同執行的。
mysiam表不支持事務處理,同時mysiam表不支持外鍵。外鍵不用說了吧?不知道的話,去網上查吧。
同時,在執行數據庫寫入的操做(insert,update,delete)的時候,mysiam表會鎖表,而innodb表會鎖行。通俗點說,就是你執行了一個update語句,那麼mysiam表會將整個表都鎖住,其餘的insert和delete、update都會被拒之門外,等到這個update語句執行完成後纔會被依次執行。
而鎖行,就是說,你執行update語句是,只會將這一條記錄進行鎖定,只有針對這條記錄的其餘寫入、更新操做會被阻塞並等待這條update語句執行完畢後再執行,針對其餘記錄的寫入操做不會有影響。
所以,當你的數據庫有大量的寫入、更新操做而查詢比較少或者數據完整性要求比較高的時候就選擇innodb表。當你的數據庫主要以查詢爲主,相比較而言更新和寫入比較少,而且業務方面數據完整性要求不那麼嚴格,就選擇mysiam表。由於mysiam表的查詢操做效率和速度都比innodb要快
myslq innodb
我發現同事在項目作壓力測試的時候,誤解了innodb_flush_log_at_trx_commit的含義,認爲配置爲0是不寫日誌,因此性能高。
配置項說明
0
若是innodb_flush_log_at_trx_commit的值爲0,log buffer每秒就會被刷寫日誌文件到磁盤,提交事務的時候不作任何操做。(執行是由mysql的master thread線程來執行的。主線程中每秒會將重作日誌緩衝寫入磁盤的重作日誌文件(REDO LOG)中。不論事務是否已經提交。)默認的日誌文件是ib_logfile0,ib_logfile1
1
當設爲默認值1的時候,每次提交事務的時候,都會將log buffer刷寫到日誌。
2
若是設爲2,每次提交事務都會寫日誌,但並不會執行刷的操做。每秒定時會刷到日誌文件。要注意的是,並不能保證100%每秒必定都會刷到磁盤,這要取決於進程的調度。每次事務提交的時候將數據寫入事務日誌,而這裏的寫入僅是調用了文件系統的寫入操做,而文件系統是有 緩存的,因此這個寫入並不能保證數據已經寫入到物理磁盤
默認值1是爲了保證完整的ACID。固然,你能夠將這個配置項設爲1之外的值來換取更高的性能,可是在系統崩潰的時候,你將會丟失1秒的數據。設爲0的話,mysqld進程崩潰的時候,就會丟失最後1秒的事務。設爲2,只有在操做系統崩潰或者斷電的時候纔會丟失最後1秒的數據。InnoDB在作恢復的時候會忽略這個值。
刷寫的概念
刷寫實際上是兩個操做,刷(flush)和寫(write),區分這兩個概念(兩個系統調用)是很重要的。在大多數的操做系統中,把Innodb的log buffer(內存)寫入日誌(調用系統調用write),只是簡單的把數據移到操做系統緩存中,操做系統緩存一樣指的是內存。並無實際的持久化數據。
因此,一般設爲0和2的時候,在崩潰或斷電的時候會丟失最後一秒的數據,由於這個時候數據只是存在於操做系統緩存。之因此說「一般」,可能會有丟失不僅1秒的數據的狀況,好比說執行flush操做的時候阻塞了。
總結
設爲1固然是最安全的,但性能頁是最差的(相對其餘兩個參數而言,但不是不能接受)。若是對數據一致性和完整性要求不高,徹底能夠設爲2,若是隻最求性能,例如高併發寫的日誌服務器,設爲0來得到更高性能
InnoDB,MyISAM引擎對比
在數據規模較大(100萬條以上),InnoDB引擎性能有相對優點。
在數據規模較小(10萬條如下),MyISAM引擎性能有相對優點。
http://www.cnblogs.com/szx_rencaijob/archive/2010/04/28/1723211.html