MySQL存儲引擎如何選擇,索引如何選擇,索引的數據結構?

對於MySQL存儲引擎、索引類型的選擇可能大多數時候無腦選InnoDB就行了,但是理論上存儲引擎的選擇應該綜合考量事務安全、併發量、支持的索引類型等因素。

同樣對於索引類型的選擇雖然大多數情況下選B樹索引就完事了,但是B樹索引並非在任何情況下都是最優的,某些業務場景下可能選全文索引或者哈希索引更加合適。這也是面試中經常問到的基礎題。

本文主要內容是參考了MySQL官方文檔和其他網站內容結合自己的理解總結而成,希望能幫到大家,如果覺得有收穫記得關注哦!

1.1. <strong>MySQL存儲引擎

1.1.1. <strong>存儲引擎特性

參考鏈接:https://dev.mysql.com/doc/refman/5.7/en/storage-engines.html

下面以MySQL5.7為準,列舉了4個主要存儲引擎的特性對比(對MySQL官方文檔進行了順序調整和刪減):

MySQL存儲引擎如何選擇,索引如何選擇,索引的數據結構?

備註: MySQL5.6+ InnoDB支持全文索引。

1.1.2. <strong>存儲引擎應用場景

參考鏈接:

https://mp.weixin.qq.com/s/Yjh_fPgrjuhhOZyVtRQ-SA

https://blog.csdn.net/zhangyuan19880606/article/details/51217952

MySQL 5.5+的默認存儲引擎為InnoDB, 之前為MyISAM。

InnoDB和MyISAM默認的索引都是B樹索引,Memory默認的索引是哈希索引。

InnoDB支持事務,支持行級鎖,支持數據緩存,支持聚集索引,適用於大部分併發量大、數據量大的業務系統。

MyISAM擁有較高的插入、查詢速度,但不支持事物,適用於數據倉庫等場景。

MEMORY將表中的數據存儲到內存中,且支持哈希索引,因此精確查詢的速度較快,適用於數據量較小、對查詢速度要求較高的場景。

Archive插入較快,適合存儲歸檔數據,如日誌信息。

2. <strong>索引

2.1. <strong>索引原理

2.1.1. <strong>索引基礎

參考鏈接:https://tech.meituan.com/mysql_index.html

圖書館為了提高查找書籍的效率需要為書籍建立索引,數據庫為了提高數據的查詢效率也需要為數據建立索引。但數據庫索引要複雜許多,因為不僅要考慮等值查詢,還有多條件查詢(and)、範圍查詢(>、

一般訪問磁盤的成本大概是訪問內存的十萬倍左右。

一般文件系統為了提高磁盤訪問效率,當一次IO時,會把相鄰的數據也都讀取到內存緩衝區內(局部預讀性原理告訴我們,當計算機訪問一個地址的數據的時候,與其相鄰的數據也大概率會被訪問到),然後再進行查找。

2.2. <strong>索引數據結構

2.2.1. <strong>B+樹索引

參考文獻:《MySQL技術內幕-InnoDB存儲引擎第2版》

B+樹(binary plus tree)是從平衡二叉樹(左子樹的鍵值小於根節點的鍵值,右子樹的鍵值大於根節點的鍵值)演化而來,但B+樹並不是二叉樹。B+樹被廣泛應用於文件系統、數據庫中建立索引。

B+樹的簡單定義:B+樹是為磁盤或其他存儲設備設計的一種平衡查找樹。B+樹中所有記錄都是按鍵值大小順序存放在葉子節點上,各葉子節點通過指針進行連接。

數據庫中B+樹的高度一般為2~4。InnoDB中B樹索引頁大小為16KB。

通過B樹索引查找數據時的IO次數取決於b+樹的高度h,假設當前數據表的數據為N,每個磁盤塊的數據項的數量是m,則有h=log (m+1)N。即B+樹的高度取決於表的數據量和磁盤塊的大小。

B+樹的數據結構示意圖如下(其中P代表指針):

MySQL存儲引擎如何選擇,索引如何選擇,索引的數據結構?

2.2.2. <strong>哈希索引

哈希索引(Hash indexes)採用哈希表來對鍵值進行查找,時間複雜度為O(1)。

使用哈希索引時對於鍵值的等值查詢是非常快的,但是其他類型的查詢如範圍查詢、模糊查詢、排序等是不能使用哈希索引的。這是哈希索引使用比較少的主要原因。

2.2.3. <strong>全文索引

對於 select * from blog where content like '%java%'是無法使用B樹索引的。在電商網站中如果要對商品的明細進行關鍵字查詢,則需要使用全文索引。

全文索引查找條件使用 MATCH AGAINST。

全文索引(Full-text search indexes)使用倒排索引(inverted index)實現。倒排索引會記錄文本中的每個關鍵字出現在文檔中的位置。

2.3. <strong>索引分類

參考鏈接:

https://dev.mysql.com/doc/refman/5.7/en/innodb-index-types.html

https://www.2cto.com/kf/201602/490519.html

2.3.1. <strong>聚集索引

聚集索引(Clustered Index)又稱聚簇索引,其葉子節點存放記錄。

每個InnoDB 表有一個特定的索引叫做聚集索引,存儲行的數據。

如果你的表定義了主鍵那麼主鍵就是聚集索引,如果沒有定義主鍵,MySQL 會選擇第一個非空唯一索引列作為聚集索引,如果表中也沒有唯一索引,InnoDB會生成一個類似RowId的隱藏的聚集索引。

2.3.2. <strong>二級索引

二級索引(secondary indexes)又稱輔助索引、非聚簇索引,其葉子節點存放索引值及指向主鍵的指針。

除聚集索引以外的索引,統稱為二級索引,如唯一索引、普通索引、組合索引等。


分享到:


相關文章: