1. 區別:
(1)事務處理:
MyISAM是非事務安全型的,而InnoDB是事務安全型的(支持事務處理等高級處理);
(2)鎖機制不同:
MyISAM是表級鎖,而InnoDB是行級鎖;
InnoDB引擎使用了七種類型的鎖,他們分別是:
1)共享排他鎖(Shared and Exclusive Locks)
2)意向鎖(Intention Locks)
3)記錄鎖(Record Locks)
4)間隙鎖(Gap Locks)
5)Next-Key Locks
6)插入意圖鎖(Insert Intention Locks)
7)自增鎖(AUTO-INC Locks)
2.1 Shared and Exclusive Locks
共享鎖(S鎖)和排他鎖(X鎖)的概念在許多編程語言中都出現過。先來描述一下這兩種鎖在MySQL中的影響結果:
如果一個事務對某一行數據加了S鎖,另一個事務還可以對相應的行加S鎖,但是不能對相應的行加X鎖。
如果一個事務對某一行數據加了X鎖,另一個事務既不能對相應的行加S鎖也不能加X鎖。
2.2 Record Locks、Gap Locks、Next-Key Locks
這三種類型的鎖都描述了鎖定的范圍,
1)記錄鎖(Record Locks):記錄鎖鎖定索引中一條記錄。
2)間隙鎖(Gap Locks):間隙鎖要么鎖住索引記錄中間的值,要么鎖住第一個索引記錄前面的值或者最后一個索引記錄后面的值。
3)Next-Key Locks:Next-Key鎖是索引記錄上的記錄鎖和在索引記錄之前的間隙鎖的組合。
定義中都提到了索引記錄(index record)。為什么?行鎖和索引有什么關系呢?其實,InnoDB是通過搜索或者掃描表中索引來完成加鎖操作,InnoDB會為他遇到的每一個索引數據加上共享鎖或排他鎖。所以我們可以稱行級鎖(row-level locks)為索引記錄鎖(index-record locks),因為行級鎖是添加到行對應的索引上的。
三種類型鎖的鎖定范圍不同,且逐漸擴大。我們來舉一個例子來簡要說明各種鎖的鎖定范圍,假設表t中索引列有3、5、8、9四個數字值,根據官方文檔的確定三種鎖的鎖定范圍如下:
記錄鎖的鎖定范圍是單獨的索引記錄,就是3、5、8、9這四行數據。
間隙鎖的鎖定為行中間隙,用集合表示為(-∞,3)、(3,5)、(5,8)、(8,9)、(9,+∞)。
Next-Key鎖是有索引記錄鎖加上索引記錄鎖之前的間隙鎖組合而成,用集合的方式表示為(-∞,3]、(3,5]、(5,8]、(8,9]、(9,+∞)。
對于間隙鎖還需要補充三點:
《1》間隙鎖阻止其他事務對間隙數據的并發插入,這樣可有有效的解決幻讀問題(Phantom Problem)。正因為如此,并不是所有事務隔離級別都使用間隙鎖,MySQL InnoDB引擎只有在Repeatable Read(默認)隔離級別才使用間隙鎖。
《2》間隙鎖的作用只是用來阻止其他事務在間隙中插入數據,他不會阻止其他事務擁有同樣的的間隙鎖。這就意味著,除了insert語句,允許其他SQL語句可以對同樣的行加間隙鎖而不會被阻塞。
《3》對于唯一索引的加鎖行為,間隙鎖就會失效,此時只有記錄鎖起作用。
(3)select ,update ,insert ,delete 操作:
MyISAM:如果執行大量的SELECT,MyISAM是更好的選擇(因為MYISAM為表級鎖,寫操作的話會對整張表進行加鎖,高并發環境下效率極低)
InnoDB:如果你的數據執行大量的INSERT或UPDATE,出于性能方面的考慮,應該使用InnoDB表
(4)查詢表的行數不同:
MyISAM:select count() from table,MyISAM只要簡單的讀出保存好的行數,注意的是,當count()語句包含 where條件時,兩種表的操作是一樣的
InnoDB : InnoDB 中不保存表的具體行數,也就是說,執行select count(*) from table時,InnoDB要掃描一遍整個表來計算有多少行
(5)外鍵支持:
mysiam表不支持外鍵,而InnoDB支持
2. 為什么MyISAM會比Innodb 的查詢速度快。
innoDB在做SELECT的時候,要維護的東西比MYISAM引擎多很多;
1)innoDB要緩存數據塊,MYISAM只緩存索引塊, 這中間還有換進換出的減少;
2)innodb尋址要映射到塊,再到行,MYISAM 記錄的直接是文件的OFFSET,定位比innoDB要快
3)innoDB還需要維護MVCC一致(為每一行記錄添加兩個額外的隱藏的值來實現MVCC,這兩個值一個記錄這行數據何時被創建,另外一個記錄這行數據何時過期(或者被刪除)存儲這些事件發生時的系統版本號。這是一個隨著事務的創建而不斷增長的數字。每個事務在事務開始時會記錄它自己的系統版本號。每個查詢必須去檢查每行數據的版本號與事務的版本號是否相同。如當隔離級別是REPEATABLEREAD時這種策略是如何應用到特定的操作的: SELECT InnoDB必須每行數據來保證它符合兩個條件: 1、InnoDB必須找到一個行的版本,它至少要和事務的版本一樣老(也即它的版本號不大于事務的版本號)。這保證了不管是事務開始之前,或者事務創建時,或者修改了這行數據的時候,這行數據是存在的。
2、這行數據的刪除版本必須是未定義的或者比事務版本要大。這可以保證在事務開始之前這行數據沒有被刪除)
3. 應用場景
MyISAM適合:(1)做很多count 的計算;(2)插入不頻繁,查詢非常頻繁;(3)沒有事務。
InnoDB適合:(1)可靠性要求比較高,或者要求事務;(2)表更新和查詢都相當的頻繁,并且行鎖定的機會比較大的情況。