1. 程式人生 > 實用技巧 >MySQL 儲存引擎

MySQL 儲存引擎

MySQL 儲存引擎

01)InnoDB
	適合資料增刪改查
02)MyISAM
	一般儲存一些只讀的資料
03)MEMORY
	支援 HASH 索引
04)ARCHIVE
05)FEDERATED
06)EXAMPLE
07)BLACKHOLE
08)MERGE
09)NDBCLUSTER
10)CSV

# 其他儲存引擎:
1.perconaDB:XTRADB
2.mariaDB

#檢視儲存引擎
mysql> show engines;

InnoDB 和 MyISAM 儲存引擎對比

儲存構成

# MyISAM 儲存引擎,資料檔案
-rw-rw---- 1 mysql mysql  10684 7月   9 15:10 user.frm		# Frame,表結構
-rw-rw---- 1 mysql mysql    980 7月  15 09:14 user.MYD		# MyData,表資料
-rw-rw---- 1 mysql mysql   2048 7月  15 09:28 user.MYI		# MyIndex,索引

# InnoDB 儲存引擎,資料檔案
-rw-rw---- 1 mysql mysql   8710 7月  17 10:59 city.frm		# Frame,表結構
-rw-rw---- 1 mysql mysql 950272 7月  17 10:59 city.ibd		# InnoDBData,表資料、索引

事務處理

MyISAM 型別的表強調效能,執行速度比 InnoDB 快(因為沒有事務自動提交機制),但不提供事務處理的支援

InnoDB 型別的表支援事務,行級鎖,外部鍵(foreign key)等高階資料庫功能,InnoDB 的 AUTOCOMMIT 預設是開啟的,即每條 SQL 語句會預設被封裝成一個事務,自動提交,這樣會影響速度,所以最好是把多條 SQL 語句顯示放在 Begin 和 Comit 之間,組成一個事務去提交,防止多次提交導致的開銷,大大提高效能

-- 檢視 MySQL 支援的儲存引擎 
-- mysql> SHOW ENGINES;
mysql> SELECT * FROM information_schema.ENGINES WHERE ENGINE = 'InnoDB' OR ENGINE = 'MyISAM';
+--------+---------+------------------------------------------------------------+--------------+------+------------+
| ENGINE | SUPPORT | COMMENT                                                    | TRANSACTIONS | XA   | SAVEPOINTS |
+--------+---------+------------------------------------------------------------+--------------+------+------------+
| MyISAM | YES     | MyISAM storage engine                                      | NO           | NO   | NO         |
| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES          | YES  | YES        |
+--------+---------+------------------------------------------------------------+--------------+------+------------+
2 rows in set (0.00 sec)

鎖的級別

MyISAM 只支援表級鎖,MyISAM不適合於有大量查詢和修改並存的情況,那樣查詢程序會長時間阻塞。因為MyISAM是鎖表,所以某項讀操作比較耗時會使其他寫程序餓死

InnoDB 提供行級鎖(row-level locking),提供與 Oracle 型別一致的不加鎖讀取(non-locking read in
SELECTs)。也就是說適合大量查詢與修改並存的情況 ,另外,InnoDB 表的行級鎖也不是絕對的,如果在執行一個 SQL 語句時 MySQL 不能確定要掃描的範圍,InnoDB表同樣會鎖全表, 例如 update table set num=1 where name like "%aaa%"

索引差異

MyISAM:支援全文(FULLTEXT)索引
InnoDB:不支援全文(FULLTEXT)索引,但是 InnoDB 可以使用 sphinx 外掛支援全文索引,並且效果更好

另外,MyISAM 索引和資料分離,InnoDB 在一起,MyISAM 是非聚簇索引,InnoDB 的資料檔案(IBD檔案)本身就是主鍵索引檔案,這樣的索引被稱為聚簇索引

MyISAM 快取在記憶體的是索引,不是資料,而 InnoDB 快取在記憶體的是資料,相對來說,伺服器記憶體越大,InnoDB 發揮的優勢越大。

CRUD 操作

MyISAM:如果執行大量的SELECT,MyISAM是更好的選擇。
InnoDB:如果你的資料執行大量的INSERT或UPDATE,出於效能方面的考慮,應該使用InnoDB表。DELETE 從效能上InnoDB更優,但DELETE FROM table時,InnoDB不會重新建立表,而是一行一行的刪除,在innodb上如果要清空儲存有大量資料的表,最好使用truncate table這個命令。

預設設定主鍵

MyISAM:允許沒有任何索引和主鍵的表存在,索引都是儲存行的地址
InnoDB:如果沒有設定主鍵或者非空唯一索引,就會自動生成一個6位元組的主鍵(使用者不可見),資料是主索引的一部分,附加索引儲存的是主索引的值。InnoDB 的主鍵範圍更大,最大是 MyISAM 的2倍。

AUTO_INCREMENT 前提條件

MyISAM 引擎的自動增長列必須是索引,MyISAM 中必須包含該欄位的索引,如果是組合索引,自動增長可以不是第一列,他可以根據前面幾列進行排序後遞增
InnoDB 引擎的自動增長列必須是索引,InnoDB 中必須包含該欄位的索引,如果是組合索引也必須是組合索引的第一列

簡單總結(轉載

MyISAM

每個MyISAM在磁碟上儲存成三個檔案。第一個檔案的名字以表的名字開始,副檔名指出檔案型別。.frm檔案儲存表定義。資料檔案的副檔名為.MYD (MYData)。

MyISAM表格可以被壓縮,而且它們支援全文搜尋。不支援事務,而且也不支援外來鍵。如果事物回滾將造成不完全回滾,不具有原子性。在進行updata時進行表鎖,併發量相對較小。如果執行大量的SELECT,MyISAM 是更好的選擇。

MyISAM的索引和資料是分開的,並且索引是有壓縮的,記憶體使用率就對應提高了不少。能載入更多索引,而Innodb是索引和資料是緊密捆綁的,沒有使用壓縮從而會造成Innodb比MyISAM體積龐大不小

MyISAM快取在記憶體的是索引,不是資料。而InnoDB快取在記憶體的是資料,相對來說,伺服器記憶體越大,InnoDB發揮的優勢越大。

優點:查詢資料相對較快,適合大量的select,可以全文索引

缺點:不支援事務,不支援外來鍵,併發量較小,不適合大量 update

InnoDB

這種型別是事務安全的。.它與BDB型別具有相同的特性,它們還支援外來鍵。InnoDB表格速度很快。具有比BDB還豐富的特性,因此如果需要一個事務安全的儲存引擎,建議使用它。在update時表進行行鎖,併發量相對較大。如果你的資料執行大量的INSERT或UPDATE,出於效能方面的考慮,應該使用InnoDB表。

優點:支援事務,支援外來鍵,併發量較大,適合大量 update

缺點:查詢資料相對較快,不適合大量的 select

對於支援事物的 InnoDB 型別的表,影響速度的主要原因是 AUTOCOMMIT 預設設定是開啟的,而且程式沒有顯式呼叫BEGIN 開始事務,導致每插入一條都自動 Commit,嚴重影響了速度。可以在執行 sql 前呼叫 Begin,多條 sql 形成一個事物(即使 autocommit 開啟也可以),將大大提高效能。

其他細節區別

1.InnoDB不支援FULLTEXT型別的索引。

2.InnoDB 中不儲存表的具體行數,也就是說,執行select count(*) from table 時,InnoDB 要掃描一遍整個表來計算有多少行,但是 MyISAM 只要簡單的讀出儲存好的行數 即可。注意的是,當 count(*) 語句包含 where 條件時,兩種表的操作是一樣的。

3.對於 AUTO_INCREMENT 型別的欄位,InnoDB 中必須包含該欄位的索引(若是聯合索引必須是首位),但是在 MyISAM 中必須包含該欄位的索引,但若是聯合索引不必須是首位

4.DELETE FROM table 時,InnoDB 不會重新建立表,而是一行一行的刪除,在 InnoDB 上如果要清空儲存有大量資料的表,最好使用 truncate table 命令

5.LOAD TABLE FROM MASTER 操作對 InnoDB 是不起作用的,解決方法是首先把 InnoDB 表改成 MyISAM 表,匯入資料後再改成 InnoDB 表,但是對於使用的額外的 InnoDB 特性(例如外來鍵)的表不適用

其他知識點:

不是遞增的主鍵會使得插入的速度很慢,例如使用手機號或身份證號做為主鍵,所以善用 AUTO_INCREMENT

表大不可怕,可怕的是count或者高偏移limit,可以將大的 limit big 換成 limit max_id, xxxxx