深入理解MySQL索引原理(常見索引數據結構)

                 **深入理解MySQL索引原理**
                                         熊大

說索引之前我們先談下mysql 這個渣男。

它支持諸多存儲引擎,各存儲引擎對索引的支持也各不相同,因此MySQL支持多種索引類型,如BTree索引,二叉樹索引,哈希索引,有序數組、全文索引等等。

現實工作中如果一個sql比較慢分析一番說加一個索引吧。一般這個sql就會飛起那麼在這其中索引起什麼作用呢?

有人說索引就像一本書的目錄如果一本書1000頁,如果想找到某個具體的內容最簡單方法就是查看目錄然後翻到該頁即可。

常見的索引類型:

哈希索引

哈希思路很簡單,把值放在數組裏,用一個哈希函數把
key 換算成一個確定位置,然後把 value 放在數組的這個位置。

當然我們知道哈希過程中算出的值可能是一樣的那就拉出一個鏈表來記錄即可。

假如有一本戀愛寶典裏面記錄了各種戀愛祕籍那麼對呀hash如下圖

在這裏插入圖片描述

那麼其實可以看到如果是等值查詢的情況我們很容易就把值查詢出來 但是如果範圍查詢這個就比較尷尬了。
等值查詢這種情況一般noSql運用較多
備註:上面的數據結構和hashmap是否一致呢?那麼一道經典面試題map、list如何選擇

面對範圍查詢於是有序數組應運而生。那麼存儲結構如下
在這裏插入圖片描述

那麼可以看出這個簡直就是爲範圍查找量身製作的。但是如果更新數據代價有點大後續數據會挨個挪動。

二叉搜索樹也是經典的數據結構:
在這裏插入圖片描述
二叉樹的特點

就是左節點要比父節點小、右節點比父節點大。如果要查章節4那麼他會一次從1–>2—>4
理論來講二叉搜索樹是查找最快的因爲他的時間複雜度O(log(N))
當然前提是要維持這個二叉樹的平衡。

全文索引

通過建立倒排索引,可以極大的提升檢索效率,解決判斷字段是否包含的問題。

那麼我們經常使用的mysql innodb引擎是怎麼存儲數據的呢
我們都知道它採用的是btree模型假如我們有一個表如下:

innodb使用了 B+ 樹索引模型,所以數據都是存儲在 B+ 樹中的。

create table test(
id int primary key,
k int not null,
name varchar(16),index (k))engine=InnoDB;


存儲數據如下圖:
在這裏插入圖片描述

由上圖可以看出主鍵直接對應的是該行內容。而普通索引對應的是相應的主鍵
也就是說普通索引如果查找相應數據需要先找到對應主鍵然後根據主鍵在找到相應的數據。

這就是我們所說的回表。當然只查這個索引對應的內容是不需要回表的。

select * from test where id=10;
select k from test where k=300;

這兩個語句是不用回表的。第一個sql是因爲根據主鍵查詢 第二個雖然根據普通索引查詢但是隻是查詢了改字段所以也不需要回表。

索引的維護:

我們知道innodb的存儲結構是b+tree
每一個索引就是一顆b+tree 而其中每個葉子節點則是數據頁(page) 數據頁裏面是由一行行的數據組成的。
那麼對這個數據頁我們則是希望它能夠寫滿再去申請下一頁自增主鍵則滿足這個要求。當然在實際使用情況中頁可能裂開或者合併。

小知識點
假設mysql 引擎是innodb沒有主鍵它是怎麼做的?

如果沒有主鍵innodb會給默認創建一個Rowid做主鍵

主鍵如何選擇:

業務允許的情況下最好選擇自增主鍵
1、自增主鍵可以更充分的使用數據頁。
2、普通索引的空間佔用也比較小

參考:
<Mysql 實戰45講>
<結構與算法>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章