MyISAM和InnoDB是在使用MySQL最經常使用的兩個表類型,各有優缺點,視具體應用而定。基本的差異爲:MyISAM類型不支持事務處理等高級處理,而InnoDB類型支持。MyISAM類型的表強調的是性能,其執行速度比InnoDB類型更快,可是不提供事務支持,而InnoDB提供事務支持已經外部鍵等高級數據庫功能。 MyISAM是ISAM表的新版本,有以下擴展: 一、二進制層次的可移植性。 二、NULL列索引。 三、對變長行比ISAM表有更少的碎片。 四、支持大文件。 五、更好的索引壓縮。 六、更好的鍵碼統計分佈。 七、更好和更快的auto_increment處理。 InnoDB 是 MySQL 上第一個提供外鍵約束的引擎,除了提供事務處理外,InnoDB 還支持行鎖,提供和 Oracle 同樣的一致性的不加鎖讀取,能增長併發讀的用戶數量並提升性能,不會增長鎖的數量。 InnoDB 的設計目標是處理大容量數據時最大化性能,它的 CPU 利用率是其餘全部基於磁盤的關係數據庫引擎中最有效率的。 InnoDB 是一套放在 MySQL 後臺的完整數據庫系統,InnoDB 有它本身的緩衝池,能緩衝數據和索引,InnoDB 還把數據和索引存放在表空間裏面,可能包含好幾個文件,這和 MyISAM 表徹底不一樣,在 MyISAM 中,表被存放在單獨的文件中,InnoDB 表的大小隻受限於操做系統文件的大小,通常爲 2GB。 如下是一些細節和具體實現的差異: 一、InnoDB不支持FULLTEXT類型的索引。 二、InnoDB 中不保存表的具體行數,也就是說,執行select count(*) from table時,InnoDB要掃描一遍整個表來計算有多少行,可是MyISAM只要簡單的讀出保存好的行數便可。注意的是,當count(*)語句包含 where條件時,兩種表的操做是同樣的。 三、對於AUTO_INCREMENT類型的字段,InnoDB中必須包含只有該字段的索引,可是在MyISAM表中,能夠和其餘字段一塊兒創建聯合索引。 四、DELETE FROM table時,InnoDB不會從新創建表,而是一行一行的刪除。 五、LOAD TABLE FROM MASTER操做對InnoDB是不起做用的,解決方法是首先把InnoDB表改爲MyISAM表,導入數據後再改爲InnoDB表,可是對於使用的額外的InnoDB特性(例如外鍵)的表不適用。 六、InnoDB表的行鎖也不是絕對的,若是在執行一個SQL語句時MySQL不能肯定要掃描的範圍,InnoDB表一樣會鎖全表,例如update table set num=1 where name like 「%aaa%」 MyISAM和InnoDB優化: key_buffer_size - 這對MyISAM表來講很是重要。若是隻是使用MyISAM表,能夠把它設置爲可用內存的 30-40%。合理的值取決於索引大小、數據量以及負載 -- 記住,MyISAM表會使用操做系統的緩存來緩存數據,所以須要留出部份內存給它們,不少狀況下數據比索引大多了。儘管如此,須要老是檢查是否全部的 key_buffer 都被利用了 -- .MYI 文件只有 1GB,而 key_buffer 卻設置爲 4GB 的狀況是很是少的。這麼作太浪費了。若是你不多使用MyISAM表,那麼也保留低於 16-32MB 的 key_buffer_size 以適應給予磁盤的臨時表索引所需。 innodb_buffer_pool_size - 這對Innodb表來講很是重要。Innodb相比MyISAM表對緩衝更爲敏感。MyISAM能夠在默認的 key_buffer_size 設置下運行的能夠,然而Innodb在默認的 innodb_buffer_pool_size 設置下卻跟蝸牛似的。因爲Innodb把數據和索引都緩存起來,無需留給操做系統太多的內存,所以若是隻須要用Innodb的話則能夠設置它高達 70-80% 的可用內存。一些應用於 key_buffer 的規則有 -- 若是你的數據量不大,而且不會暴增,那麼無需把 innodb_additional_pool_size - 這個選項對性能影響並不太多,至少在有差很少足夠內存可分配的操做系統上是這樣。不過若是你仍然想設置爲 20MB(或者更大),所以就須要看一下Innodb其餘須要分配的內存有多少。 innodb_log_file_size 在高寫入負載尤爲是大數據集的狀況下很重要。這個值越大則性能相對越高,可是要注意到可能會增長恢復時間。我常常設置爲 64-512MB,跟據服務器大小而異。 innodb_log_buffer_size 默認的設置在中等強度寫入負載以及較短事務的狀況下,服務器性能還能夠。若是存在更新操做峯值或者負載較大,就應該考慮加大它的值了。若是它的值設置過高了,可能會浪費內存 -- 它每秒都會刷新一次,所以無需設置超過1秒所需的內存空間。一般 8-16MB 就足夠了。越小的系統它的值越小。 innodb_flush_logs_at_trx_commit 是否爲Innodb比MyISAM慢1000倍而頭大?看來也許你忘了修改這個參數了。默認值是 1,這意味着每次提交的更新事務(或者每一個事務以外的語句)都會刷新到磁盤中,而這至關耗費資源,尤爲是沒有電池備用緩存時。不少應用程序,尤爲是從 MyISAM轉變過來的那些,把它的值設置爲 2 就能夠了,也就是不把日誌刷新到磁盤上,而只刷新到操做系統的緩存上。日誌仍然會每秒刷新到磁盤中去,所以一般不會丟失每秒1-2次更新的消耗。若是設置爲 0 就快不少了,不過也相對不安全了 -- MySQL服務器崩潰時就會丟失一些事務。設置爲 2 指揮丟失刷新到操做系統緩存的那部分事務。 table_cache -- 打開一個表的開銷可能很大。例如MyISAM把MYI文件頭標誌該表正在使用中。你確定不但願這種操做太頻繁,因此一般要加大緩存數量,使得足以最大限度地緩存打開的表。它須要用到操做系統的資源以及內存,對當前的硬件配置來講固然不是什麼問題了。若是你有200多個表的話,那麼設置爲 1024 也許比較合適(每一個線程都須要打開表),若是鏈接數比較大那麼就加大它的值。我曾經見過設置爲 100,000 的狀況。 thread_cache -- 線程的建立和銷燬的開銷可能很大,由於每一個線程的鏈接/斷開都須要。我一般至少設置爲 16。若是應用程序中有大量的跳躍併發鏈接而且 Threads_Created 的值也比較大,那麼我就會加大它的值。它的目的是在一般的操做中無需建立新線程。 query_cache -- 若是你的應用程序有大量讀,並且沒有應用程序級別的緩存,那麼這頗有用。不要把它設置太大了,由於想要維護它也須要很多開銷,這會致使MySQL變慢。一般設置爲 32-512Mb。設置完以後最好是跟蹤一段時間,查看是否運行良好。在必定的負載壓力下,若是緩存命中率過低了,就啓用它。 sort_buffer_size --若是你只有一些簡單的查詢,那麼就無需增長它的值了,儘管你有 64GB 的內存。搞很差也許會下降性能。