MySql MyISAM與InnoDB的區別

一、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是索引文件

如何選擇:

  1. 是否要支持事務,若是要請選擇innodb,若是不須要能夠考慮MyISAM;
  2. 若是表中絕大多數都只是讀查詢,能夠考慮MyISAM,若是既有讀也有寫,請使用InnoDB。
  3. 系統奔潰後,MyISAM恢復起來更困難,可否接受;
  4. MySQL5.5版本開始Innodb已經成爲Mysql的默認引擎(以前是MyISAM),說明其優點是有目共睹的,若是你不知道用什麼,那就用InnoDB,至少不會差。

InnoDB爲何推薦使用自增ID做爲主鍵?

自增ID能夠保證每次插入時B+索引是從右邊擴展的,能夠避免B+樹和頻繁合併和分裂(對比使用UUID)。若是使用字符串主鍵和隨機主鍵,會使得數據隨機插入,效率比較差。

innodb引擎的4大特性

插入緩衝(insert buffer),二次寫(double write),自適應哈希索引(ahi),預讀(read ahead)

相關文章
相關標籤/搜索