Mysql索引結構與索引原理及hash索引介紹

2021-10-19 18:32:06 字數 2898 閱讀 3792

mysql索引主要包括四種,btree索引、hash索引、full-text全文索引、r-tree索引,因為作為一名php開發者,並不是專業的dba,在這裡只需要了解第一種開發相關的btree索引。

索引的本質:mysql官方對索引的定義為:索引(index)是幫助mysql高效獲取資料和排序的資料結構。

資料庫查詢是資料庫的主要功能之一,最基本的查詢演算法是順序查詢(linear search)時間複雜度為o(n),顯然在資料量很大時效率很低。優化的查詢演算法如二分查詢(binary search)、二叉樹查詢(binary tree search)等,雖然查詢效率提高了。但是各自對檢索的資料都有要求:二分查詢要求被檢索資料有序,而二叉樹查詢只能應用於二叉查詢樹上,但是資料本身的組織結構不可能完全滿足各種資料結構(例如,理論上不可能同時將兩列都按順序進行組織)。所以,在資料之外,資料庫系統還維護著滿足特定查詢演算法的資料結構。這些資料結構以某種方式引用(指向)資料,這樣就可以在這些資料結構上實現高階查詢演算法。這種資料結構就是索引。

如上圖左邊是橫列**,也就是真是的資料,右邊是一棵樹。資料越來越多,**增長的越來越高,相反,如果樹越來越高,查詢的層次越來越多,我們如果能用三次找到,盡量別用四次,儘量減少一次磁碟i/o,也就是這棵樹廣度越來越廣,廣度廣了同一層就代表枝葉多。

在資料庫裡面,在物理儲存上,有單位的說法叫段、區、塊,就是一種衡量單位。 上圖中的磁塊也就是相當於儲存一段範圍的資料。

看上圖中,一棵b+樹,淺藍色的塊我們稱之為乙個磁碟塊,可以看到每個磁碟塊包含幾個資料項(深藍色所示)和指標(黃色所示),如磁碟塊1包含資料項17和35,包含指標p1、p2、p3。

我如果要找29這個數字,那麼從根找,p1表示小與17的,p2表示大於17小與35的,p3表示大於35的,那麼往下走,真實的資料存在於葉子節點,也就是第三層,即3、5、9、10、13...依次往右看。假設我要查詢非葉子節點(第二層),不儲存真實的資料,只儲存指引搜尋方向的資料項,如17、35並不存在真實的資料表中,也就是相當於乙個參考值。如果查詢29,但是我們先給參考項,那麼根據圖示,29在17和35之間,鎖定磁碟塊1的p2指標,找到指標p2,記憶體時間非常短,相比磁碟的io可以忽略不計,那麼下來之後,找到磁碟塊3,也就是不見得載入磁碟塊2,這裡就第二次io了,那麼看圖,29在26和30之間,那麼又指向指標p2,再往下就載入到了磁碟塊8的記憶體,發生第三次io,同時記憶體中做二分查詢找到29,結束查詢,總共三次io。

看btree也就是三層樓那麼高,也就是盡量把資料橫向擴,高度矮比較好,真實的情況是,3層的b+樹 可以表示上百萬的資料,如果上百萬的資料查詢只需三次io,效能提高將是巨大的,如果沒有所用,每個資料項都要發生一次io,那麼總共需要上百萬次的io,顯然成本非常高。

mysql 中的 hash 索引

採用 hash 進行檢索效率非常高,基本上一次檢索就可以找到資料,而 b+ 樹需要自頂向下依次查詢,多次訪問節點才能找到資料,中間需要多次 i/o 操作,從效率來說 hash 比 b+ 樹更快。

我們來看下 hash 索引的示意圖:

鍵值 key 通過 hash 對映找到桶 bucket。在這裡桶(bucket)指的是乙個能儲存一條或多條記錄的儲存單位。乙個桶的結構包含了乙個記憶體指標陣列,桶中的每行資料都會指向下一行,形成鍊錶結構,當遇到 hash 衝突時,會在桶中進行鍵值的查詢。

那麼什麼是 hash 衝突呢?

如果桶的空間小於輸入的空間,不同的輸入可能會對映到同乙個桶中,這時就會產生 hash 衝突,如果 hash 衝突的量很大,就會影響讀取的效能。

通常 hash 值的位元組數比較少,簡單的 4 個位元組就夠了。在 hash 值相同的情況下,就會進一步比較桶(bucket)中的鍵值,從而找到最終的資料行。

hash 值的位元組數多的話可以是 16 位、32 位等,比如採用 md5 函式就可以得到乙個 16 位或者 32 位的數值,32 位的 md5 已經足夠安全,重複率非常低。

我們模擬一下 hash 索引。關鍵字如下所示,每個字母的內部編碼為字母的序號,比如 a 為 01,y 為 25。我們統計內部編碼平方的第 8-11 位(從前向後)作為 hash 值:

hash 索引與 b+ 樹索引的區別

我們之前講到過 b+ 樹索引的結構,hash 索引結構和 b+ 樹的不同,因此在索引使用上也會有差別。

hash 索引不能進行範圍查詢,而 b+ 樹可以。這是因為 hash 索引指向的資料是無序的,而 b+ 樹的葉子節點是個有序的鍊錶。

hash 索引不支援聯合索引的最左側原則(即聯合索引的部分索引無法使用),而 b+ 樹可以。對於聯合索引來說,hash 索引在計算 hash 值的時候是將索引鍵合併後再一起計算 hash 值,所以不會針對每個索引單獨計算 hash 值。因此如果用到聯合索引的乙個或者幾個索引時,聯合索引無法被利用。

hash 索引不支援 order by 排序,因為 hash 索引指向的資料是無序的,因此無法起到排序優化的作用,而 b+ 樹索引資料是有序的,可以起到對該字段 order by 排序優化的作用。同理,我們也無法用 hash 索引進行模糊查詢,而 b+ 樹使用 like 進行模糊查詢的時候,like 後面前模糊查詢(比如 % 開頭)的話就可以起到優化作用。

對於等值查詢來說,通常 hash 索引的效率更高,不過也存在一種情況,就是索引列的重複值如果很多,效率就會降低。這是因為遇到 hash 衝突時,需要遍歷桶中的行指標來進行比較,找到查詢的關鍵字,非常耗時。所以,hash 索引通常不會用到重複值多的列上,比如列為性別、年齡的情況等。

MySQL 索引與索引原理

本人菜鳥一枚,如有理解不對,請大神多多指正!一 索引 1 什麼是索引?答 索引類似於一本書的目錄,便於資料快速高效的查詢,也可以解釋為資料按照某個特定的規則去儲存排序資料 2 索引的型別?答 索引可以分為 普通索引,唯一索引,主鍵索引和組合索引 2.1 普通索引 最基本的一種索引方式,沒有什麼限制 ...

mysql 索引 實現 MySQL索引原理及實現

主要內容 索引本質 mysql索引實現 前言索引是儲存引擎快速查詢記錄的一種資料結構,它對於效能非常關鍵,尤其是對於表資料量較大的情況,索引對效能的影響愈發重要。所以了解索引對於效能優化極其重要。索引本質 mysql儲存引擎使用索引的方法,類似於讀一本書時如果想查詢特定的主題的話,需要先看書的目錄,...

MySQL索引及索引資料結構

索引是幫助mysql高效獲取資料的排好序的資料結構 索引分類 索引失效的情況 模糊查詢時,第乙個查詢字元是不確定值 或 時,索引失效 select name from stu where name like e 索引失效 select name from stu where name like h ...