MySQL中InnoDB和MyISAM的存儲引擎的差異

mysql數據庫區別于其他數據庫的很重要的一個特點就是其插件式的表存儲引擎,其基于表,而不是數據庫。由于每個存儲引擎都有其特點,因此我們可以針對每一張表來挑選最合適的存儲引擎。

MySQL中InnoDB和MyISAM的存儲引擎的差異

作為dba,我們應該深刻的認識存儲引擎。今天介紹兩種最常見的存儲引擎和它們的區別:InnoDB和MyISAM。

InnoDB存儲引擎

InnoDB存儲引擎支持事務,其設計目標主要就是面向OLTP(On Line Transaction Processing 在線事務處理)的應用。特點為行鎖設計、支持外鍵,并支持非鎖定讀。從5.5.8版本開始,InnoDB成為了mysql的默認存儲引擎。

InnoDB存儲引擎采用聚集索引(clustered)的方式來存儲數據,因此每個表都是按照主鍵的順序進行存放,如果沒有指定主鍵,InnoDB會為每行自動生成一個6字節的ROWID作為主鍵。

MyISAM存儲引擎

MyISAM存儲引擎不支持事務、表鎖設計,支持全文索引,主要面向OLAP(On Line Analytical Processing 聯機分析處理)應用,適用于數據倉庫等查詢頻繁的場景。在5.5.8版本之前,MyISAM是MySQL的默認存儲引擎。該引擎代表著對海量數據進行查詢和分析的需求。它強調性能,因此在查詢的執行速度比InnoDB更快。

InnoDB和MyISAM的區別

事務

為了數據庫操作的原子性,我們需要事務。保證一組操作要么都成功,要么都失敗,比如轉賬的功能。我們通常將多條SQL語句放在begin和commit之間,組成一個事務。

InnoDB支持,MyISAM不支持。

主鍵

由于InnoDB的聚集索引,其如果沒有指定主鍵,就會自動生成主鍵。
MyISAM支持沒有主鍵的表存在。

外鍵

為了解決復雜邏輯的依賴,我們需要外鍵。比如高考成績的錄入,必須歸屬于某位同學,我們就需要高考成績數據庫里有準考證號的外鍵。

InnoDB支持,MyISAM不支持。

索引

為了優化查詢的速度,進行排序和匹配查找,我們需要索引。比如所有人的姓名從a-z首字母進行順序存儲,當我們查找zhangsan或者第44位的時候就可以很快的定位到我們想要的位置進行查找。

InnoDB是聚集索引,數據和主鍵的聚集索引綁定在一起,通過主鍵索引效率很高。如果通過其他列的輔助索引來進行查找,需要先查找到聚集索引,再查詢到所有數據,需要兩次查詢。

MyISAM是非聚集索引,數據文件是分離的,索引保存的是數據的指針。

從InnoDB 1.2.x版本,MySQL5.6版本后,兩者都支持全文索引。

auto_increment自增

對于自增數的字段,InnoDB要求該列必須是索引,同時必須是索引的第一個列,否則會報錯:

mysql> create table test(     -> a int auto_increment,     -> b int,     -> key(b,a)     -> ) engine=InnoDB; ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key

把(b,a)順序替換為(a,b)即可。

而MyISAM可以將該字段與其他字段隨意順序組成成聯合索引。

表行數

很常見的需求是看表中有多少條數據,此時我們需要select count(*) from table_name。

InnoDB不保存表行數,需要進行全表掃描。MyISAM用一個變量保存,直接讀取該值,更快。當時當帶有where查詢的時候,兩者一樣。

存儲

數據庫的文件都是需要在磁盤中進行存儲,當應用需要時再讀取到內存中。一般包含數據文件、索引文件。

InnoDB分為:

  • .frm表結構文件
  • .ibdata1共享表空間
  • .ibd表獨占空間
  • .redo日志文件

MyISAM分為三個文件:

  • .frm存儲表定義
  • .MYD存儲表數據
  • .MYI存儲表索引

執行速度

如果你的操作是大量的查詢操作,如SELECT,使用MyISAM性能會更好。
如果大部分是刪除和更改的操作,使用InnoDB。

InnoDB和MyISAM的索引都是B+樹索引,通過索引可以查詢到數據的主鍵,不熟悉B+樹的可以查看MySQL InnoDB索引原理和算法。兩者的性能區別主要在于查詢到數據主鍵后兩者的處理方式卻不同。

InnoDB會緩存索引和數據文件,一般以16KB為一個最小單元(數據頁大?。┖痛疟P進行交互,InnoDB在查詢到索引數據后實際得到的是主鍵的ID,它需要在內存中的數據頁中查找該行的全部數據,但如果該數據不是加載過的熱數據,還需要進行數據頁的查找和替換,這其中可能牽涉到多次I/O操作和內存中數據查找,導致耗時較高。

而MyISAM存儲引擎只緩存索引文件,不緩存數據文件,其數據文件的緩存直接使用操作系統的緩存,這點非常獨特。此時相同的空間能夠加載更多的索引,因此當緩存空間有限時,MyISAM的索引數據頁替換次數會更少。根據前面我們知道MyISAM的文件分為MYI和MYD,當我們通過MYI查找到主鍵ID時,其實得到是MYD數據文件的offset偏移量,查找數據比InnoDB尋址映射要快的多。

但由于MyISAM是表鎖,而InnoDB支持行鎖,因此在牽涉到大量寫操作時,InnoDB的并發性能比MyISAM好很多。同時InnoDB還通過MVVC多版本控制來提高并發讀寫性能。

delete刪除數據

調用delete from table時,MyISAM會直接重建表,InnoDB會一行一行的刪除,但是可以用truncate table代替。參考: mysql清空表數據的兩種方式和區別。

MyISAM僅支持表鎖,每次操作鎖定整張表。
InnoDB支持行鎖,每次操作鎖住最小數量的行數據。

表鎖相比于行鎖消耗的資源更少,且不會出現死鎖,但同時并發性能差。行鎖消耗更多的資源,速度較慢,且可能發生死鎖,但是因為鎖定的粒度小、數據少,并發性能好。如果InnoDB的一條語句無法確定要掃描的范圍,也會鎖定整張表。

當行鎖發生死鎖的時候,會計算每個事務影響的行數,然后回滾行數較少的事務。

數據恢復

MyISAM崩潰后無法快速的安全恢復。InnoDB有一套完善的恢復機制。

數據緩存

MyISAM僅緩存索引數據,通過索引查詢數據。InnoDB不僅緩存索引數據,同時緩存數據信息,將數據按頁讀取到緩存池,按LRU(Latest Rare Use 最近最少使用)算法來進行更新。

如何選擇存儲引擎

創建表的語句都是相同的,只有最后的type來指定存儲引擎。

MyISAM

1、大量查詢總count

2、查詢頻繁,插入不頻繁

3、沒有事務操作

InnoDB

1、需要高可用性,或者需要事務

2、表更新頻繁

推薦學習:MySQL教程

? 版權聲明
THE END
喜歡就支持一下吧
點贊15 分享