MySQL: InnoDB 還是 MyISAM?

工程師WWW發表於2016-02-18
MyISAM儲存引擎
       MyISAM是 預設儲存引擎。它基於更老的ISAM程式碼,但有很多有用的擴充套件。MyISAM儲存引擎的一些特徵:
      所有資料值先儲存低位元組。這使得資料機和作業系統分離。二進位制輕便性的唯一要求是機器使用補碼(如最近20年的機器有的一樣)和IEEE浮點格式(在主流機器中也完全是主導的)。唯一不支援二進位制相容性的機器是嵌入式系統。這些系統有時使用特殊的處理器。
        先儲存資料低位元組並不嚴重地影響速度;資料行中的位元組一般是未聯合的,從一個方向讀未聯合的位元組並不比從反向讀更佔用更多的資源。伺服器上的獲取列值的程式碼與其它程式碼相比並不顯得時間緊。

         大檔案(達63位檔案長度)在支援大檔案的檔案系統和作業系統上被支援。
         當把刪除和更新及插入混合的時候,動態尺寸的行更少碎片。這要通過合併相鄰被刪除的塊,以及若下一個塊被刪除,就擴充套件到下一塊來自動完成。
         每個MyISAM表最大索引數是64。 這可以通過重新編譯來改變。每個索引最大的列數是16個。
         最大的鍵長度是1000位元組。這也可以通過編譯來改變。對於鍵長度超過250位元組的情況,一個超過1024位元組的的鍵塊被用上。
         BLOB和TEXT列可以被索引。
        NULL值被允許在索引的列中。這個佔每個鍵的0-1個位元組。
         所有數字鍵值以高位元組為先被儲存以允許一個更高地索引壓縮。
        當記錄以排好序的順序插入(就像你使用一個AUTO_INCREMENT列之時),索引樹被劈開以便高節點僅包含一個鍵。這改善了索引樹的空間利用率。
         每表一個AUTO_INCREMEN列的內部處理。MyISAM為INSERT和UPDATE操作自動更新這一 列。這使得AUTO_INCREMENT列更快(至少10%)。在序列頂的值被刪除之後就不能再利用。(當AUTO_INCREMENT列被定義為多列索 引的最後一列,可以出現重使用從序列頂部刪除的值的情況 )。AUTO_INCREMENT值可用ALTER TABLE或myisamch來重置。
         如果資料檔案中間的表沒有自由塊了,在其它執行緒從表讀的同時,你可以INSERT新行到表中。(這被認識為併發操作 )。自由塊的出現是作為刪除行的結果,或者是用比當前內容多的資料對動態長度行更新的結果。當所有自由塊被用完(填滿),未來的插入又變成併發。
         你可以把資料檔案和索引檔案放在不同目錄,用DATA DIRECTORY和INDEX DIRECTORY選項CREATE TABLE以獲得更高的速度,請參閱13.1.5節,“CREATE TABLE語法”。
         每個字元列可以又不同的字符集。
        在MyISAM索引檔案裡又一個標誌,它表明表是否被正確關閉。如果用--myisam-recover選項啟動mysqld,MyISAM表在開啟得時候被自動檢查,如果被表被不恰當地關閉,就修復表。
        如果你用--update-state選項執行myisamchk,它標註表為已檢查。myisamchk --fast只檢查那些沒有這個標誌的表。
        myisamchk --analyze為部分鍵儲存統計資訊,也為整個鍵儲存統計資訊。
        myisampack可以打包BLOB和VARCHAR列。

MyISAM也支援下列特徵:

         支援true VARCHAR型別;VARCHAR列以儲存在2個位元組中的長度來開始。
         有VARCHAR的表可以有固定或動態記錄長度。
         VARCHAR和CHAR列可以多達64KB。
         一個被搞亂的已計算索引對可對UNIQUE來使用。這允許你在表內任何列的合併上有UNIQUE。(儘管如此,你不能在一個UNIQUE已計算索引上搜尋)。

InnoDB儲存引擎
InnoDB給MySQL提供 了具有提交,回滾和崩潰恢復能力的事務安全(ACID相容)儲存引擎。InnoDB鎖定在行級並且也在SELECT語句提供一個Oracle風格一致的非 鎖定讀。這些特色增加 了多使用者部署和效能。沒有在InnoDB中擴大鎖定的需要,因為在InnoDB中行級鎖定適合非常小的空間。InnoDB也支援FOREIGN KEY強制。在SQL查詢中,你可以自由地將InnoDB型別的表與其它MySQL的表的型別混合起來,甚至在同一個查詢中也可以混合。
InnoDB是為處理巨大資料量時的最大效能設計。它的CPU效率可能是任何其它基於磁碟的關聯式資料庫引擎所不能匹敵的。

InnoDB儲存引擎被完全與MySQL伺服器整合,InnoDB儲存引擎為在主記憶體中快取資料和索引而維持它自己的緩衝池。 InnoDB儲存它的表&索引在一個表空間中,表空間可以包含數個檔案(或原始磁碟分割槽)。這與MyISAM表不同,比如在MyISAM表中每個表被存在 分離的檔案中。InnoDB 表可以是任何尺寸,即使在檔案尺寸被限制為2GB的作業系統上。

InnoDB預設地被包含在MySQL二進位制分發中。Windows Essentials installer使InnoDB成為Windows上MySQL的 預設表。

InnoDB被用來在眾多需要高效能的大型資料庫站點上產生。著名的Internet新聞站點Slashdot.org執行在 InnoDB上。Mytrix, Inc.在InnoDB上儲存超過1TB的資料,還有一些其它站點在InnoDB上處理平均每秒800次插入/更新的負荷。

InnoDB和MyISAM的區別
區別概述:
MyISAM 是MySQL中預設的儲存引擎,一般來說不是有太多人關心這個東西。決定使用什麼樣的儲存引擎是一個很tricky的事情,但是還是值我們去研究一下,這裡的文章只考慮 MyISAM 和InnoDB這兩個,因為這兩個是最常見的。

下面先讓我們回答一些問題:
你的資料庫有外來鍵嗎?
你需要事務支援嗎?
你需要全文索引嗎?
你經常使用什麼樣的查詢模式?
你的資料有多大?


思考上面這些問題可以讓你找到合適的方向,但那並不是絕對的。如果你需要事務處理或是外來鍵,那麼InnoDB 可能是比較好的方式。如果你需要全文索引,那麼通常來說 MyISAM是好的選擇,因為這是系統內建的,然而,我們其實並不會經常地去測試兩百萬行記錄。所以,就算是慢一點,我們可以通過使用Sphinx從 InnoDB中獲得全文索引。

資料的大小,是一個影響你選擇什麼樣儲存引擎的重要因素,大尺寸的資料集趨向於選擇InnoDB方式,因為其支援事務處理和故障恢復。資料庫的在小 決定了故障恢復的時間長短,InnoDB可以利用事務日誌進行資料恢復,這會比較快。而MyISAM可能會需要幾個小時甚至幾天來幹這些事,InnoDB 只需要幾分鐘。

您運算元據庫表的習慣可能也會是一個對效能影響很大的因素。比如: COUNT() 在 MyISAM 表中會非常快,而在InnoDB 表下可能會很痛苦。而主鍵查詢則在InnoDB下會相當相當的快,但需要小心的是如果我們的主鍵太長了也會導致效能問題。大批的inserts 語句在MyISAM下會快一些,但是updates 在InnoDB 下會更快一些——尤其在併發量大的時候。

所以,到底你檢使用哪一個呢?根據經驗來看,如果是一些小型的應用或專案,那麼MyISAM 也許會更適合。當然,在大型的環境下使用MyISAM 也會有很大成功的時候,但卻不總是這樣的。如果你正在計劃使用一個超大資料量的專案,而且需要事務處理或外來鍵支援,那麼你真的應該直接使用InnoDB方 式。但需要記住InnoDB 的表需要更多的記憶體和儲存,轉換100GB 的MyISAM 表到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特性(例如外來鍵)的表不適用。

另外,InnoDB表的行鎖也不是絕對的,如果在執行一個SQL語句時MySQL不能確定要掃描的範圍,InnoDB表同樣會鎖全表,例如update table set num=1 where name like “%aaa%”


提升InnoDB效能的方法:
MyISAM和InnoDB儲存引擎效能差別並不是很大,針對InnoDB來說,影響效能的主要是 innodb_flush_log_at_trx_commit 這個選項,如果設定為1的話,那麼每次插入資料的時候都會自動提交,導致效能急劇下降,應該是跟重新整理日誌有關係,設定為0效率能夠看到明顯提升,當然,同 樣你可以SQL中提交“SET AUTOCOMMIT = 0”來設定達到好的效能。另外,還聽說通過設定innodb_buffer_pool_size能夠提升InnoDB的效能,但是我測試發現沒有特別明顯 的提升。

基本上我們可以考慮使用InnoDB來替代我們的MyISAM引擎了,因為InnoDB自身很多良好的特點,比如事務支援、儲存 過程、檢視、行級鎖定等等,在併發很多的情況下,相信InnoDB的表現肯定要比MyISAM強很多,當然,相應的在my.cnf中的配置也是比較關鍵 的,良好的配置,能夠有效的加速你的應用。
任何一種表都不是萬能的,只用恰當的針對業務型別來選擇合適的表型別,才能最大的發揮MySQL的效能優勢。

相關文章