Mysql優化 B+Tree索引和Hash索引


B+Tree索引

  B+Tree和普通的B-Tree不大一樣。有個網站可以體驗這些數據結構:https://www.cs.usfca.edu/~galles/visualization/Algorithms.html

  先看一下B-Tree

  

 

  設定最大深度為3,插入10個數字,數據結構如上,他與普通的二叉樹區別在於每個節點有多個數據,相當於橫向擴展,減少深度。

  為什么要減少深度:當數據量比較大的時候,mysql無法將索引全部加載到內存中,只能逐一加載磁盤頁,每個磁盤頁對應樹的節點。造成大量磁盤IO操作(最壞情況下為樹的高度)。平衡二叉樹由於樹深度過大而造成磁盤IO讀寫過於頻繁,進而導致效率低下。所以,我們為了減少磁盤IO的次數,就你必須降低樹的深度,將“瘦高”的樹變得“矮胖”。

  B樹在這一點上已經比二叉樹先進很多了,但對比B+樹還是差了點,為了更好說明B+樹,需要提到的是在Mysql中,B數的節點中都帶有存儲數據。

  依然到網站中去體驗一下B+樹:

  

 

   可以看到兩個特點:

    1.同樣是三層數據,但是這里多了一層數據層,那是因為,B+樹只有最后的葉子節點才會帶有數據,其他的都是索引。

    2.數據間帶有一個指針

  這些特點有什么用呢?

  1.在Mysql的B樹索引方式中,每個節點的存儲容量是固定的,如果節點中存儲了數據,意味着,該節點只能存儲更少的索引,這將導致查找數據時需要經過更多的IO,反過來,B+樹可以更快找到對應的數據

  2.B樹的查找只需找到匹配元素即可,最好情況下查找到根節點,最壞情況下查找到葉子結點,所說性能很不穩定,而B+樹每次必須查找到葉子結點,性能穩定

  3.在范圍查詢方面,B+樹的優勢更加明顯。B樹的范圍查找需要不斷依賴中序遍歷。首先二分查找到范圍下限,在不斷通過中序遍歷,知道查找到范圍的上限即可。整個過程比較耗時。而B+樹的范圍查找則簡單了許多。首先通過二分查找,找到范圍下限,然后同過葉子結點的鏈表順序遍歷,直至找到上限即可,整個過程簡單許多,效率也比較高。

  比如,當查找索引值大於某個數值時,根據數據節點的向后指針,B+樹只要找到臨界點后,直接可以找到后面的所有數據,而不用回到根節點上再去查找。

Hash索引

  哈希索引是基於哈希表實現的,只有精確匹配索引所有的列的查詢才有效。對於每一行數據,存儲引擎都會對所有的索引列計算一個哈希碼,哈希碼是一個較小的值,並且不同鍵值的行計算出來的哈希碼也不一樣。哈希索引是將所有的哈希碼存儲在索引中,同時在哈希表中保存指向每個數據行的指針。

  在MySQL中,只有Memory 引擎顯示支持哈希索引。這也是Memory 引擎表的默認索引類型,Memory 引擎同時也支持B-Tree索引。這里插播一個Mysql的存儲引擎,如果涉及到索引的類型的設計,還是有必要參考一下的

    

 

   可以主要到,如果需要支持外鍵的話,那基本只能選擇InnoDB類型。

  回到主題,當采用了Hash索引之后,在數據庫中根據索引查找一個記錄時非常快的事情:

    1.根據索引值計算hash,速度極快

    2.根據hash值獲取存儲地址,速度極快

    3.根據存儲地址獲取數據,速度極快

  hash索引雖然查詢快,但是那僅限於精確查詢,他的缺陷同樣不小:

    哈希索引只包含哈希值和行指針,而不存儲字段值,所以不能上使用索引中的值來避免讀取行。
    哈希索引數據並不是按照索引值順序存儲的,所以也就無法用於排序。
    哈希索引也不支持部分索引列匹配查找,因為哈希索引始終是使用索引列的全部內容來計算哈希值的。
    哈希索引只支持等值比較查詢,包括=、IN( )、<=>(注意<>和<=>是不同的操作)。也不支持任何范圍查詢,如 WHERE price > 100 ;
    訪問哈希索引的數據結構非常快,除非有許多哈希沖突
    如果哈希沖突很多,一些索引維護操作的代價也會很高。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM