MySQL InnoDB與MyISAM存儲引擎差異
前言:
之前簡單介紹過 MySQL 常用的存儲引擎,今天對兩個主流的存儲簡單分析下差異,書上沒有參考的筆試題解答註解;
差異:
MyISAM 只支持表鎖,不支持事務,表損壞率較高。較老的存儲引擎。
它分為2種類型的文件:以 MYD 作為後綴名的數據文件和以 MYI 作為後綴名的索引文件。 MyISAM 讀寫並發不如 InnoDB,適用於INSERT較多的場景,且支持直接復制文件,用以備份數據, 是 MySQL 公司開發的,物理文件主要有數據文件,日誌文件和索引文件,並且這三個文件是單獨存在。 InnoDB 支持行鎖,支持事務,支持行級鎖,Crash(崩潰)後具有 Revcover(還原)機制, 只有 ibd 文件,分為數據區和索引區,有較好的讀寫並發能力,但做 COUNT 運算時相當消耗CPU, 是 InnoDB 公司開發的。物理文件有日誌文件,數據文件和索引文件。 其中,索引文件和數據文件是放在一個目錄下,可以設置共享文件、獨享文件兩種格式。
MyISAM |
InnoDB |
|
構成上的區別 |
每個MyISAM在磁盤上存儲成三個文件。 每一個文件的名字就是表的名字,文件名都和表名相同, 擴展名指出文件類型。
表定義的擴展名為.frm(frame,存儲表定義); 數據文件的擴展名為.MYD(MYData,存儲數據); 索引文件的擴展名是.MYI(MYIndex,存儲索引);
數據文件和索引文件可以放置在不同的目錄下, 平均分布I/O,獲得更快的速度。
|
只有ibd文件,分為數據區和索引區,有較好的讀寫並發能力。
物理文件有:日誌文件、數據文件和索引文件。 其中,索引文件和數據文件是放在一個目錄下,可以設置共享文件與獨享文件兩種格式。 基於磁盤的資源是 InnoDB 表空間數據文件和它的日誌文件, InnoDB 表的大小只受限於操作系統文件的大小,一般為2GB(單個文件)。
InnoDB 存儲引擎提供了具有提交、回滾和崩潰恢復能力的事務安全。 但是對比 MyISAM 的存儲引擎,InnoDB 寫的處理效率差一些, 並且會占用更多的磁盤空間以保留數據和索引。 |
事務處理上方面 |
MyISAM類型的表強調的是性能,其執行速度比InnoDB類型更快, 但是不提供事務支持。
|
InnoDB提供事務支持事務、外鍵等高級數據庫功能。
|
SELECT UPDATE INSERT DELETE |
如果執行大量的 SELECT,那麽 MyISAM 是更好的選擇。 |
(1)如果執行大量的INSERT或UPDATE,那麽出於性能方面的考慮,應該使用InnoDB表。 (2)當執行DELETE FROM table時,InnoDB不會重建表,而是一行一行地刪除。 (3)LOAD TABLE FROM MASTER 操作對 InnoDB 是不起作用的, 解決方法是首先把 InnoDB 表改成 MyISAM 表,導入數據後再改成 InnoDB 表, 但是對於使用的額外的 InnoDB 特性(例如外鍵)的表不適用。 |
清空表 |
MyISAM 會重建表。
|
InnoDB 是一行一行地刪除,效率非常慢。
|
對AUTO_INCREMENT列的操作 |
MyISAM 為 INSERT 和 UPDATE 操作自動更新這一列。 AUTO_INCREMENT 值可用 ALTER TABLE 來重置。 對於AUTO_INCREMENT類型的字段,InnoDB中必須包含只有該字段的索引,但是在MyISAM表中,可以和其它字段一起建立聯合索引。
|
如果為一個表指定AUTO_INCREMENT列, 那麽在數據字典裏的InnoDB表句柄包含一個名為自動增長計數器的計數器, 它被用在為該列賦新值,自動增長計數器僅被存儲在主內存中,而不是存在磁盤上。 InnoDB中必須包含只有該字段的索引。
|
表的行數 |
當執行SQL語句“SELECT COUNT(*) FROM TABLE”時, MyISAM只是簡單地讀出保存好的行數,需要註意的是, 當COUNT(*)語句包含WHERE條件時, MyISAM和InnoDB的操作是一樣的。
|
InnoDB中不保存表的具體行數,也就是說, 當執行SELECT COUNT(*) FROM TABLE時,InnoDB要掃描一遍整個表來計算行數。
|
鎖 |
表級鎖定(更新時鎖定整個表):其鎖定機制是表級索引, 這雖然可以讓鎖定的實現成本很小,但是也同時大大降低了其並發性能。 不支持行級鎖,只支持並發插入的表鎖,主要用於高負載的SELECT。
|
提供行級鎖(locking on row level), 提供與 Oracle 類型一致的不加鎖讀取(non-locking read), 另外,InnoDB 表的行鎖也不是絕對的, 如果在執行一個 SQL 語句時 MySQL 不能確定要掃描的範圍, 那麽 InnoDB 表同樣會鎖全表, 例如 UPDATE TABLE T_TEST_LHR SET NUM=1 WHERE NAME LIKE "%LHR%"。
|
MySQL InnoDB與MyISAM存儲引擎差異