一、InnoDB支持事務,MyISAM不支持,對於InnoDB每一條SQL語言都默認封裝成事務,自動提交,這樣會影響速度,因此最好把多條SQL語言放在begin和commit之間,組成一個事務;sql
二、InnoDB支持外鍵,而MyISAM不支持。對一個包含外鍵的InnoDB錶轉爲MYISAM會失敗;優化
三、InnoDB是彙集索引,使用B+Tree做爲索引結構,數據文件是和(主鍵)索引綁在一塊兒的(表數據文件自己就是按B+Tree組織的一個索引結構),必需要有主鍵,經過主鍵索引效率很高。可是輔助索引須要兩次查詢,先查詢到主鍵,而後再經過主鍵查詢到數據。所以,主鍵不該該過大,由於主鍵太大,其餘索引也都會很大。ui
MyISAM是非彙集索引,也是使用B+Tree做爲索引結構,索引和數據文件是分離的,索引保存的是數據文件的指針。主鍵索引和輔助索引是獨立的。
也就是說:InnoDB的B+樹主鍵索引的葉子節點就是數據文件,輔助索引的葉子節點是主鍵的值;而MyISAM的B+樹主鍵索引和輔助索引的葉子節點都是數據文件的地址指針。3d
四、InnoDB不保存表的具體行數,執行select count(*) from table時須要全表掃描。而MyISAM用一個變量保存了整個表的行數,執行上述語句時只須要讀出該變量便可,速度很快(注意不能加有任何WHERE條件);指針
那麼爲何InnoDB沒有了這個變量呢?code
由於InnoDB的事務特性,在同一時刻表中的行數對於不一樣的事務而言是不同的,所以count統計會計算對於當前事務而言能夠統計到的行數,而不是將總行數儲存起來方便快速查詢。InnoDB會嘗試遍歷一個儘量小的索引除非優化器提示使用別的索引。若是二級索引不存在,InnoDB還會嘗試去遍歷其餘聚簇索引。
若是索引並無徹底處於InnoDB維護的緩衝區(Buffer Pool)中,count操做會比較費時。能夠創建一個記錄總行數的表並讓你的程序在INSERT/DELETE時更新對應的數據。和上面提到的問題同樣,若是此時存在多個事務的話這種方案也不太好用。若是獲得大體的行數值已經足夠知足需求能夠嘗試SHOW TABLE STATUSblog
五、Innodb不支持全文索引,而MyISAM支持全文索引,在涉及全文索引領域的查詢效率上MyISAM速度更快高;PS:5.7之後的InnoDB支持全文索引了索引
六、MyISAM表格能夠被壓縮後進行查詢操做事務
七、InnoDB支持表、行(默認)級鎖,而MyISAM支持表級鎖字符串
InnoDB的行鎖是實如今索引上的,而不是鎖在物理行記錄上。潛臺詞是,若是訪問沒有命中索引,也沒法使用行鎖,將要退化爲表鎖。
例如:
t_user(uid, uname, age, sex) innodb; uid PK 無其餘索引 update t_user set age=10 where uid=1; 命中索引,行鎖。 update t_user set age=10 where uid != 1; 未命中索引,表鎖。 update t_user set age=10 where name='chackca'; 無索引,表鎖。
八、InnoDB表必須有主鍵(用戶沒有指定的話會本身找或生產一個主鍵),而Myisam能夠沒有
九、Innodb存儲文件有frm、ibd,而Myisam是frm、MYD、MYI
Innodb:frm是表定義文件,ibd是數據文件
Myisam:frm是表定義文件,myd是數據文件,myi是索引文件
如何選擇:
- 是否要支持事務,若是要請選擇innodb,若是不須要能夠考慮MyISAM;
- 若是表中絕大多數都只是讀查詢,能夠考慮MyISAM,若是既有讀也有寫,請使用InnoDB。
- 系統奔潰後,MyISAM恢復起來更困難,可否接受;
- MySQL5.5版本開始Innodb已經成爲Mysql的默認引擎(以前是MyISAM),說明其優點是有目共睹的,若是你不知道用什麼,那就用InnoDB,至少不會差。
InnoDB爲何推薦使用自增ID做爲主鍵?
自增ID能夠保證每次插入時B+索引是從右邊擴展的,能夠避免B+樹和頻繁合併和分裂(對比使用UUID)。若是使用字符串主鍵和隨機主鍵,會使得數據隨機插入,效率比較差。
innodb引擎的4大特性
插入緩衝(insert buffer),二次寫(double write),自適應哈希索引(ahi),預讀(read ahead)