Adaptive Hash Index(以下簡稱 AHI)估計是 MySQL 的各大特性中,大家都知道名字但最說不清原理的一個特性。本期圖解我們為大家解析一下 AHI 是如何構建的。
AHI 在實現上就是一個哈希表:從某個檢索條件到某個數據頁的哈希表,仿佛並不複雜,但其中的關竅在於哈希表不能太大(哈希表維護本身就有成本,哈希表太大則成本會高於收益),又不能太小(太小則緩存命中率太低,沒有任何收益)。
這就是 AHI(中文名:自適應哈希索引)中"自適應"的用途:建立一個"不大不小剛剛好"的哈希表。
本文主要討論 MySQL 是如何建立起一個"剛剛好"的 AHI 的,如圖 1 所示:需要經歷三個關卡,才能為某個數據頁建立 AHI,之後的查詢才能使用到該 AHI。
顯而易見,如果我們為了一個很少出現的檢索條件建立 AHI,肯定是入不敷出的。
在此我們插播一個新概念 hash info,hash info 是用來描述一次檢索的條件與索引匹配程度(即此次檢索是如何使用索引的)。建立AHI時,就可以根據匹配程度,抽取數據中匹配的部分,作為 AHI 的鍵。關卡 2 就是為了找到經常使用的 hash info。hash info 包括以下三項:我們通過一個例子來簡要介紹 hash info 中第一項。假設一張表 table1,其索引是(A1, A2)兩列構成的索引:關卡 2 就是為了找出經常使用的 hash info,作為建立 AHI 的依據。如果我們為表中所有數據建立 AHI,那 AHI 就失去了緩存的意義:內存已不足以存放其身軀,必然要放到磁碟上,那麼其成本顯然已經不低於收益。回憶一下,AHI 是為了縮短 B+ 樹的查詢成本設計的,如果把自己再放到磁碟上,就得變成另一顆 B+ 樹(B+ 樹算法是處理磁碟查詢的高效結構),如此循環往復,嗚呼哀哉。因此我們只能為表中經常被查詢的部分數據建立 AHI。所以關卡 3 的任務就是找出哪些數據頁是經常被使用的數據頁。
終於可以開始建立 AHI 了, 我們舉個例子說明如何建立 AHI。假設以上三個關卡的通關情況如下:表 table1 具有 4 列:A1,A2,A3,B1。具有兩個索引 Idx1(A1,A2,A3) 和 Idx2(B1)