B-tree 索引提高 MySQL 查詢效率的原理

在MySQL中,我們常用的存儲引擎 InnoDB 和 MyISAM 的索引都是B-Tree 索引。大家都知道,建立索引的目的便是優化慢查詢,那麼慢查詢究竟慢在哪裏呢?

查詢時間

一個sql查詢的時間分爲 等待時間執行時間

等待時間,即sql執行之前所等待的時間。對於mysql數據庫來說,在執行某些操作時,InnoDB會鎖行,MyISAM會鎖表。當即將開始一個新查詢時,如果查詢所操作的表或者行正被鎖定,那麼就會有等待時間(一般時間相當短,可以忽略。如果過長,應檢查數據庫)。

執行時間,sql查詢的執行時間分爲2個步驟:
查詢:找到符合要求的行。
取出:將找到的行的數據取回。

時間分佈如下圖:

這裏寫圖片描述

建立索引的目的便是爲了減少執行時間。

B-tree索引

B-tree是一種常見的數據結構。對於 InnoDB 和 MyISAM 來說,在未加索引的情況下,查詢一條數據只能進行全表掃描。效率十分低下,添加索引後,通過索引檢索數據,效率則會提高千倍萬倍。

那麼b-tree的查詢爲何如此快速呢?
B-tree 可以說是多階的二叉樹,下面我們以二叉樹查找來演示,原理與b-tree基本相同:

二叉樹具有以下性質:
- 任意節點的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值;
- 任意節點的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值;
- 任意節點的左、右子樹也分別爲二叉查找樹;
- 沒有鍵值相等的節點。

假設將主鍵索引存入一顆二叉樹,那麼在查找主鍵爲27的數據時,二叉樹查找與隊列查找對比如下:
這裏寫圖片描述
(圖中step數忽略了頂層比較)

使用二叉樹後,比較次數由11次降到了4次。

在大數據時這一點更加明顯:如圖,27所在二叉樹的第四層,需要進行4次比較操作。
假設數據量夠大,要查找的目標id在第32層存儲,那麼則需要比較32次便可找到目標記錄的id。那麼11層二叉樹存儲了多少數據呢?二叉樹每層存儲量都會翻倍,那麼第32層則存儲了 2^32個數據,再加上前10層的數據,總數據量達到了 2^(33)-2 個,大約40多億條。假設沒有索引,直接全表掃描,那麼平均則需要檢索20億次,才能找到目標數據。

索引排序

建立索引,不僅能夠大大提高查詢的效率。對排序效率也有很大提高。
在進行排序操作時,索引樹由根節點開始展開,左子樹排在父節點之前,右子樹排在父節點之後,組成一個整體,再與更上一層父節點重複操作。如圖:

這裏寫圖片描述

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