千萬級數據mysql索引原理深入剖析

第一章:mysql索引的本質

1.索引的重要性

從mysql數據庫中查找書籍,就類似於從圖書館找書,如果書比較少,那麼查找的速度會比較快,如果書比較多的時候,那麼查找的速度就會非常的慢。這個時候圖書的分類管理就顯得非常重要了,圖書分類管理就類似於索引(或者理解成給所有的圖書設定目錄)。

書很少時
在這裏插入圖片描述

書很多時
在這裏插入圖片描述

2.mysql索引常見的面試題

問一:數據庫中最常見的慢查詢優化方式是什麼?
答:加索引可以優化查詢。

問二:爲什麼加索引能優化慢查詢?
答:因爲索引是一種優化查詢的數據結構,比如mysql中的索引是用B+樹實現的。而B+樹就是一種數據結構,可以利用索引快速查找數據。所以能優化查詢。

問三:哪些數據結構可以提高查詢速度?
答:哈希表 完全平衡二叉樹 B樹 B+樹等。

問四:那這些數據結構既然都能優化查詢速度,那mysql爲什麼選擇使用B+樹?
這個問題的答案就需要慢慢道來啦!!

3.mysql索引的本質

mysql中有這樣一張表,user表,表結構的數據如下

在這裏插入圖片描述

假如在沒有索引的情況下,當你執行如下的sql語句,那麼執行的速度相對來說比較慢。
Sql語句如下:select * from user where id = 7

在沒有索引的情況下,爲什麼查詢的速度會比較慢呢??
因爲數據都是存儲在磁盤上的,那麼再執行sql語句的時候,一定會去磁盤上讀取相關的數據,那就會產生磁盤IO。如果沒有索引,當你查詢id=7的數據時,那麼會進行7次磁盤的IO操作,比較耗費時間。
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

在這裏插入圖片描述

當需要從磁盤讀取數據的時候,操作系統會將數據邏輯地址傳給磁盤,磁盤的控制電路按照尋址邏輯將邏輯地址翻譯成物理地址,即確定要讀的數據在哪個磁道,哪個扇區。爲了讀取這個扇區的數據,需要講磁頭放到這個扇區的上方。爲了實現這一點,磁頭需要移動對準相應的磁道。這個過程叫尋道,所消耗的時間叫做尋道時間。然後磁盤旋轉將目標扇區旋轉到磁頭下,這個過程消耗的時間叫做旋轉時間。

爲什麼要使用索引?

其目的就是爲了減少磁盤的IO操作,這樣就可以提高查詢數據的速度。

索引本質是什麼?

索引是幫助快速檢索出數據的數據結構。
索引的作用是快速檢索出數據。
索引的本質就是一種數據結構。也就是說你創建了一個索引,其實mysql的數據庫會幫你創建一個數據結構,然後使用該數據結構來存儲數據,該數據結構就是索引。

第二章:mysql索引底層原理

1.常見的數據結構

哈希表(散列表)、二叉樹(完全平衡二叉樹)、B樹、B+樹等等。

2.哈希表

哈希表是一種以鍵-值(key-value)的方式存儲數據的結構,我們只要輸入待查找的值(即key),就可以找到其對應的值(即Value)。哈希的思路很簡單,把值放在數組裏,用一個哈希函數把key換算成一個確定的位置,然後把value放在數組的這個位置,即idx = Hash(key)。如果出現哈希衝突,就採用拉鍊法解決。
因爲哈希表中存放的數據不是有序的,因此不適合做區間查詢,適用於只有等值查詢的場景。

假如mysql的索引使用哈希表數據結構。默認主鍵列建立索引。
在這裏插入圖片描述

哈希表的缺點:因爲節點的數據容易出現重合,查詢數據還需要拿到真實的數據做對比,效率會變低。並且也不適合做範圍查詢。

3.二叉樹

採用二叉樹做爲索引的數據結構。
二叉樹是一顆相對平衡的有序二叉樹,對其進行插入,查找,刪除等操作性能都比較好。
特點:它的左子節點的值比父節點的值要小,右節點的值要比父節點的大。
自己測試例子
在這裏插入圖片描述

二叉樹的優點:可以優化磁盤IO的次數。節點存在有順序,可以進行範圍的查詢。
二叉樹的缺點:插入數據的速度會比較慢,因爲會更改數據結構。不平衡的問題,會產生傾斜的二叉樹。

4.完成平衡二叉樹

插入數據會平衡,但是插入的時候會改變樹的結構。插入的數據的時候比較慢。而且樹的層級會變高,會增加磁盤IO的次數。
二叉樹是有順序的,範圍查找都是支持的。
在這裏插入圖片描述

5.B+樹

B+樹

B樹或者B+樹的節點可以存儲多個數據,所以相對於完全平衡二叉樹的高度肯定會低,那麼就會降低磁盤IO的次數。
B+樹相對於B樹有數據的冗餘,葉子節點中的數據是有順序的。那麼再進行順序查找的時候就非常的方便,只要在葉子節點順序向後遍歷即可。

第三章:mysql索引底層原理分析

1.mysql中是如何使用B+樹的

mysql中Innodb和myisam存儲引擎默認都是使用B+樹數據結構做索引的,存儲的數據結構如下:
在這裏插入圖片描述

爲什麼只有葉子節點會存儲數據,而非葉子節點不存儲數據呢?

局部性原理:當一個數據被用到時,其附近的數據也可能被使用,所以操作系統爲了提高效率,讀取數據的時候往往不是嚴格按需讀取,而是每次都會預讀,即使只需要一個字節,操作系統也會從這個位置開始,順序向後讀取一定長度的數據放入內存中,這裏的長度叫做頁。也就是計算機操作系統操作磁盤的基本單位,一般操作系統中一頁的大小爲 4kb。
在mysql中可以使用如下的命令查看Innodb引擎頁的默認大小
SHOW GLOBAL STATUS LIKE ‘Innodb_page_size’
Mysql的頁的大小默認是16kb,B+數的設計非常適合讀取數據。
如果節點又存儲數據和索引,數據比較多,索引就比較少,那麼樹的高度就越高。導致磁盤IO變多,效率變低。

2.B+數高度和存儲數據的條數

一個節點能存儲16KB的數據,這是mysql默認的節點大小,一頁16KB。
假設一行記錄的大小爲1kb(其實已經比較大了)
那麼一個葉子節點就能存儲16條數據。
非葉子節點裏面存儲的是索引的值和指針,mysql默認的索引值大小是8B,指針大小是6B,合在一起是14B。那麼非葉子節點可以存儲的索引+指針的個數爲:
16*1024/14 = 1170 個

那麼如果數的高度是2層,葉子節點的個數也就是 1170個,那麼可以存儲的數據條數爲:1170 * 16 = 18720條。

如果樹的高度是3層,那每個葉子節點可以存儲的條數爲:1170117016= 21902400條

3.myisam引擎存儲結構

可以使用命令創建一張新的表結構,使用myisam引擎來創建。Myisam引擎的索引採用的非聚集索引,索引和表數據是分開存儲的。
在這裏插入圖片描述

user2.frm文件是創建表的文件
user2.MYD文件是表的數據文件
user2.MYI文件是索引文件

myisam引擎的索引結構圖。
索引文件
在這裏插入圖片描述

數據文件
在這裏插入圖片描述

Myisam引擎通過索引查找數據的時候,通過索引值找到對應的地址,通過地址找到數據。

如果已name字段設置索引,效果是一樣的。

4.Innodb引擎存儲結構

數據文件
file

user.frm是創建表的文件
user.ibd是數據+索引文件
索引Innodb引擎是聚集索引,索引和數據文件在一起的。
在這裏插入圖片描述

如果已name字段設置索引,那就是二級索引。葉子節點中存儲的該列的數據和主鍵值,也就意味着還需要再通過主鍵去查找一次數據。
在這裏插入圖片描述

學習更多架構免費課程請關注:java架構師免費課程
每晚20:00直播分享高級java架構技術
掃描加入QQ交流羣264572737
在這裏插入圖片描述
進入羣內免費領取海量java架構面試題
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

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