1. 程式人生 > 其它 >MySQL中MyISAM和InnoDB

MySQL中MyISAM和InnoDB

先講講MyISAM:

MyISAM 儲存引擎是 MySQL 中常見的儲存引擎,曾(MySQL 5.1及之前版本)是 MySQL 的預設儲存引擎。

MyISAM 是基於 ISAM 儲存引擎發展起來的。實際上那會還沒有儲存引擎的概念,ISAM 只是一種演算法,或者說是資料的處理方式。如同 SQL Server/Oracle 這類產品一樣,MySQL 對錶物件的管理方式只有一種。隨著 MySQL 架構的不斷髮展和演進,最終才引入外掛式儲存引擎的概念,ISAM 也進化為 MyISAM 並一直作為 MySQL 資料庫的預設儲存引擎,直到 MySQL 5.5 版本才被 InnoDB 引擎取代了預設儲存引擎的地位。

下面主要從優缺點和物理儲存等方面來介紹 MyISAM 儲存引擎。

優缺點

作為 MySQL 最早的儲存引擎之一,MyISAM 有一些已經開發出來很多年的特性,可以滿足使用者的實際需求。例如全文索引、壓縮、空間函式(GIS)等。但 MySQL 官方的重心早就不在 MyISAM 引擎上了,所以近些年來,MyISAM 一直沒有很大的改進,也存在著許多的缺陷。

優點
*佔用空間小
*訪問速度快,對事務完整性沒有要求或以 SELECT、INSERT 為主的應用基本上都可以使用這個引擎來建立表
*可以配合鎖,實現作業系統下的複製備份
*支援全文檢索(InnoDB 在 MySQL 5.6 版本以後也支援全文檢索)
*資料緊湊儲存,因此可獲得更小的索引和更快的全表掃描效能。

1. 加鎖與併發

MyISAM 對整張表加鎖,而不是針對行。讀取時會對需要讀到的所有表加共享鎖,寫入時對錶加排他鎖。但是在表有讀取查詢的同時,也可以往表中插入新的記錄(這被稱為併發插入)。

2. 修復

對於 MyISAM 表,MySQL 可以手工(執行命令 CHECK TABLE tablename)或者自動執行檢查和修復(執行命令 REPAIR TABLE tablename)操作,但這裡說的修復和事務恢復以及崩潰修復是不同的概念。

另外,如果 MySQL 伺服器已經關閉,也可以通過 myisamchk 命令列工具進行檢查和修復操作

3. 索引特性

MyISAM 支援以下 3 種類型的索引:

1)B-Tree 索引
B-Tree 索引,顧名思義,就是所有的索引節點都按照 balance tree 的資料結構來儲存,所有的索引資料節點都在葉節點。

2)R-Tree 索引
R-Tree 索引的儲存方式和 b-tree 索引有一些區別,主要設計用於為儲存空間和多維資料的欄位做索引,所以對於目前的 MySQL 版本來說,
也僅支援 geometry 型別的欄位作索引。
3)Full-text 索引 Full-text 索引就是全文索引,它的儲存結構也是 b-tree。主要是為了解決需要用 like 查詢時的低效問題。 MyISAM 上面三種索引型別中,最經常使用的就是 B-Tree 索引了,偶爾會使用到 Full-text,但是 R-Tree 索引一般系統中都是很少用到的。
另外 MyISAM 的 B-Tree 索引有一個較大的限制,那就是參與一個索引的所有欄位的長度之和不能超過 1000 位元組。
缺點
  • 不支援事務的完整性和併發性
  • 不支援行級鎖,使用表級鎖,併發性差
  • 主機宕機後,MyISAM表易損壞,災難恢復性不佳
  • 資料庫崩潰後無法安全恢復
  • 只快取索引,資料的快取是利用作業系統緩衝區來實現的,可能會引發過多的系統呼叫,且效率不佳

物理儲存

MyISAM 儲存引擎的表在資料庫中被儲存成 3 個物理檔案,檔名與表名相同。副檔名為 frm、MYD 和 MYI。其中:

  • frm 為副檔名的檔案儲存表的結構;
  • MYD 為副檔名的檔案儲存資料,其是 MYData 的縮寫;
  • MYI 為副檔名的檔案儲存索引,其是 MYIndex 的縮寫。不管表有多少索引,都是存放在同一個 .MYI 檔案中。


MyISAM 型別的資料檔案和索引檔案可以放置在不同的目錄,平均分佈 IO,以此來獲得更快的速度。

要指定索引檔案和資料檔案的路徑,需要在建立表的時候通過 DATA DIRECTORY 和 INDEX DIRECTORY 語句指定,也就是說不同 MyISAM 表的索引檔案和資料檔案可以放置到不同的路徑下。檔案路徑需要是絕對路徑,並且具有訪問許可權。

雖然每一個 MyISAM 的表資料都存放在後綴名為 .MYD 的檔案中,但是每個檔案的存放格式可能並不完全一樣。因為 MyISAM 支援 3 種不同的資料存放格式,即靜態型、動態型和壓縮型。

1)靜態型

靜態型為 MyISAM 儲存引擎的預設儲存格式,其欄位是固定長度,這樣每個記錄都是固定長度的,這種儲存方式儲存非常迅速,容易快取,出現故障容易恢復。

缺點是佔用的空間比動態表多。靜態型的表的資料在儲存的時候會按照列的寬度定義去補足空格,但是在應用訪問的時候並不會得到這些空格,空格在返回給應用之前就被去掉了。

需要注意的是,如果需要儲存的內容後面本來就帶有空格,那麼在返回結果的時候也會被去掉。這一點開發人員在編寫程式的時候需要特別注意,因為靜態表是預設的儲存格式,開發人員可能並沒有意識到這一點,從而丟失了尾部的空格。

2)動態型

動態型包含變長欄位,記錄的長度不是固定的。這樣儲存的優點是佔用的空間相對較少,但是頻繁的更新刪除記錄會產生碎片,需要定期執行 OPTIMIZE TABLE 語句或 myisamchk -r 命令來改善效能,並且出現故障的時候恢復相對比較困難。

3)壓縮型

與上面兩種格式相比,壓縮型的表就顯得特殊一些。壓縮型的表需要使用 myisampack 工具建立,解壓縮則用另外的 myisamchk 命令。壓縮表是制度的,不支援新增或修改記錄。

壓縮表是基於靜態或動態格式表的,優點在於佔用的磁碟空間非常小,可以減少磁碟 I/O,從而提升查詢效能。因為每個記錄都是被單獨壓縮的,所以只有非常小的開支。

理論上,MyISAM 儲存引擎的表可以被多個數據庫例項同時使用同時操作,但是一般不建議這樣做,關於這點,MySQL 官方的使用者手冊中也有提到,建議儘量不要在多個 mysqld 之間共享 MyISAM 儲存檔案

如果表在建立並匯入資料以後,不會再進行修改操作,這樣的表或許適合採用 MyISAM 壓縮表。

再講講MyISAM與InnoDB 的區別

區別:
1. InnoDB支援事務,MyISAM不支援,對於InnoDB每一條SQL語言都預設封裝成事務,自動提交,這樣會影響速度,所以最好把多條SQL語言放在begin和commit之間,組成一個事務;

2. InnoDB支援外來鍵,而MyISAM不支援。對一個包含外來鍵的InnoDB錶轉為MYISAM會失敗;

3. InnoDB是聚集索引,使用B+Tree作為索引結構,資料檔案是和(主鍵)索引綁在一起的(表資料檔案本身就是按B+Tree組織的一個索引結構),必須要有主鍵,通過主鍵索引效率很高。但是輔助索引需要兩次查詢,先查詢到主鍵,然後再通過主鍵查詢到資料。因此,主鍵不應該過大,因為主鍵太大,其他索引也都會很大。

MyISAM是非聚集索引,也是使用B+Tree作為索引結構,索引和資料檔案是分離的,索引儲存的是資料檔案的指標。主鍵索引和輔助索引是獨立的。

也就是說:InnoDB的B+樹主鍵索引的葉子節點就是資料檔案,輔助索引的葉子節點是主鍵的值;而MyISAM的B+樹主鍵索引和輔助索引的葉子節點都是資料檔案的地址指標

4. InnoDB不儲存表的具體行數,執行select count(*) from table時需要全表掃描。而MyISAM用一個變數儲存了整個表的行數,執行上述語句時只需要讀出該變數即可,速度很快(注意不能加有任何WHERE條件);

那麼為什麼InnoDB沒有了這個變數呢?

因為InnoDB的事務特性,在同一時刻表中的行數對於不同的事務而言是不一樣的,因此count統計會計算對於當前事務而言可以統計到的行數,而不是將總行數儲存起來方便快速查詢。InnoDB會嘗試遍歷一個儘可能小的索引除非優化器提示使用別的索引。如果二級索引不存在,InnoDB還會嘗試去遍歷其他聚簇索引。
如果索引並沒有完全處於InnoDB維護的緩衝區(Buffer Pool)中,count操作會比較費時。可以建立一個記錄總行數的表並讓你的程式在INSERT/DELETE時更新對應的資料。和上面提到的問題一樣,如果此時存在多個事務的話這種方案也不太好用。如果得到大致的行數值已經足夠滿足需求可以嘗試SHOW TABLE STATUS

5. Innodb不支援全文索引,而MyISAM支援全文索引,在涉及全文索引領域的查詢效率上MyISAM速度更快高;PS:5.7以後的InnoDB支援全文索引了

6. MyISAM表格可以被壓縮後進行查詢操作

7. 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';    無索引,表鎖。

8、InnoDB表必須有唯一索引(如主鍵)(使用者沒有指定的話會自己找/生產一個隱藏列Row_id來充當預設主鍵),而Myisam可以沒有

9、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)

————————————————
referance:https://blog.csdn.net/qq_35642036/article/details/82820178