一文詳解MySQL數(shù)據(jù)庫(kù)自適應(yīng)哈希
什么是哈希索引

哈希索引是基于內(nèi)存的支持,底層結(jié)構(gòu)就是鏈?zhǔn)焦1?,增刪改查的時(shí)間復(fù)雜度都是O(1)。
通過(guò)將索引鍵(如數(shù)據(jù)庫(kù)表的主鍵、Redis 的 Key)經(jīng)過(guò)哈希函數(shù)計(jì)算得到哈希值,再將哈希值映射到對(duì)應(yīng)的存儲(chǔ)位置(槽位),從而快速定位數(shù)據(jù)的物理地址或內(nèi)存地址。
InnoDB自適應(yīng)哈希索引
AHI 完全存儲(chǔ)在 InnoDB 的 緩沖池(Buffer Pool) 中,屬于緩沖池內(nèi)部的一塊專用內(nèi)存區(qū)域,并非獨(dú)立于緩沖池的單獨(dú)內(nèi)存空間。
結(jié)構(gòu)
哈希表數(shù)組(Hash Bucket Array)
- 核心存儲(chǔ)結(jié)構(gòu):數(shù)組的每個(gè)元素(哈希桶)是一個(gè)指向 “哈希鏈表” 的指針。
- 哈希函數(shù):InnoDB 會(huì)對(duì)索引鍵(如 B+ 樹索引的鍵值)計(jì)算哈希值,根據(jù)哈希值將鍵值映射到對(duì)應(yīng)的哈希桶。
- 內(nèi)存占用:哈希表數(shù)組的大小由 InnoDB 動(dòng)態(tài)調(diào)整,默認(rèn)初始大小較小,隨熱點(diǎn)數(shù)據(jù)增多而擴(kuò)容(避免哈希沖突過(guò)于頻繁)。
哈希鏈表(Hash Chain)
- 解決哈希沖突:當(dāng)多個(gè)索引鍵的哈希值映射到同一個(gè)哈希桶時(shí),會(huì)通過(guò)鏈表形式存儲(chǔ)(鏈地址法)。
- 鏈表節(jié)點(diǎn)內(nèi)容:每個(gè)節(jié)點(diǎn)存儲(chǔ) 3 類核心信息:
- 索引鍵的完整值(或前綴,取決于 AHI 的構(gòu)建策略);
- 對(duì)應(yīng)的 B+ 樹索引類型(聚簇索引 / 二級(jí)索引);
- 數(shù)據(jù)頁(yè)在緩沖池中的內(nèi)存地址(或頁(yè)號(hào)),以及頁(yè)內(nèi)數(shù)據(jù)的偏移量(直接定位到具體行數(shù)據(jù))。
不使用自適應(yīng)哈希索引的查詢過(guò)程

- 解析與優(yōu)化器決策:優(yōu)化器選擇
name二級(jí)索引(等值查詢適合二級(jí)索引),避免全表掃描。 - 二級(jí)索引 B + 樹遍歷(從根到葉):
- 與聚簇索引遍歷邏輯一致:從二級(jí)索引根節(jié)點(diǎn)開始,逐層查找
name='苗'對(duì)應(yīng)的子節(jié)點(diǎn),直到葉子節(jié)點(diǎn)。 - 二級(jí)索引葉子節(jié)點(diǎn)存儲(chǔ)「索引鍵(username)+ 主鍵 id」(如
('苗', 100)),通過(guò)二分查找定位到username='苗'對(duì)應(yīng)的主鍵 id=100。 - 關(guān)鍵:二級(jí)索引遍歷同樣無(wú) AHI 加速,需完整走 B + 樹逐層查找(啟用 AHI 時(shí),熱點(diǎn)
username會(huì)通過(guò)哈希表直接獲取主鍵 id)。
- 與聚簇索引遍歷邏輯一致:從二級(jí)索引根節(jié)點(diǎn)開始,逐層查找
- 回表查詢(聚簇索引查找):
- 拿到主鍵 id=100 后,需通過(guò)聚簇索引查詢完整行數(shù)據(jù)(即回表),回表流程與聚簇索引等值查詢完全一致(從根到葉遍歷 B + 樹,定位葉子節(jié)點(diǎn)的完整行)。
- 數(shù)據(jù)整合與返回:將回表獲取的完整行數(shù)據(jù)返回給應(yīng)用。
使用自適應(yīng)哈希索引的查詢過(guò)程
在AHI中,key就是經(jīng)常被訪問(wèn)的索引,value就是索引對(duì)應(yīng)的物理數(shù)據(jù)頁(yè)的位置。

InnoDB 會(huì)持續(xù)監(jiān)控所有索引的查詢操作,尤其是等值查詢。它會(huì)為每個(gè)索引鍵維護(hù)一個(gè)訪問(wèn)計(jì)數(shù)器,記錄其被查詢的次數(shù)。當(dāng)某個(gè)索引鍵的訪問(wèn)次數(shù)達(dá)到內(nèi)部閾值時(shí),InnoDB 會(huì)將其視為熱點(diǎn)數(shù)據(jù),并觸發(fā) AHI 的構(gòu)建。
當(dāng)后續(xù)有相同的等值查詢時(shí),InnoDB 會(huì)先檢查 AHI 的哈希表:
- 如果找到匹配的索引鍵(哈希命中),直接通過(guò)存儲(chǔ)的物理地址訪問(wèn)數(shù)據(jù)頁(yè),跳過(guò) B+ 樹的遍歷。
- 如果未找到(哈希未命中),則 fallback 到傳統(tǒng)的 B+ 樹查詢,并更新該索引鍵的訪問(wèn)計(jì)數(shù)器。
基于主鍵的查找,大部分都是哈希查找。
AHI 的哈希表大小是有限的(默認(rèn)占用緩沖池的 1/6),當(dāng)哈希表滿時(shí),InnoDB 會(huì)根據(jù)LRU(最近最少使用)算法淘汰掉訪問(wèn)頻率較低的索引鍵,為新的熱點(diǎn)數(shù)據(jù)騰出空間。當(dāng)索引鍵對(duì)應(yīng)的記錄被刪除或更新時(shí),InnoDB 會(huì)同步更新 AHI 中的對(duì)應(yīng)條目,確保數(shù)據(jù)一致性。
條件
只有滿足以下條件,二級(jí)索引的索引鍵才會(huì)被 InnoDB 自動(dòng)加入到自適應(yīng)哈希索引中:
1. 查詢類型必須是等值查詢
AHI 僅支持等值查詢(
=),不支持范圍查詢(>、<、BETWEEN)、模糊查詢(LIKE)或排序(ORDER BY)等。
2. 索引鍵值的訪問(wèn)頻率足夠高
InnoDB 會(huì)監(jiān)控索引鍵的訪問(wèn)次數(shù),只有當(dāng)某個(gè)索引鍵被查詢的次數(shù)達(dá)到一定閾值時(shí),才會(huì)將其加入 AHI。
這個(gè)閾值由 InnoDB 內(nèi)部算法動(dòng)態(tài)決定,無(wú)法手動(dòng)配置。
3. 索引鍵值的選擇性足夠好
選擇性是指索引鍵值的唯一程度(
選擇性 = 唯一索引值數(shù)量 / 總記錄數(shù))。AHI 更傾向于緩存選擇性高的索引鍵(如主鍵、唯一索引),因?yàn)檫@些索引鍵的等值查詢命中率更高,能顯著提升性能。
對(duì)于選擇性極低的索引(如
gender字段,只有男 / 女兩個(gè)值),即使訪問(wèn)頻率高,InnoDB 也可能不會(huì)將其加入 AHI,因?yàn)楣_突的概率太高,優(yōu)化效果有限。
4. 索引必須是 B+ 樹索引
AHI 僅作用于 InnoDB 的B+ 樹索引(包括聚簇索引和二級(jí)索引),不支持哈希索引、全文索引或空間索引。
總結(jié)
自適應(yīng)哈希索引可以看作為索引的索引,只有熱索引才有資格建立起哈希索引以方便數(shù)據(jù)頁(yè)的查找。但維護(hù)哈希索引也需要一定的開銷,要根據(jù)具體的情況來(lái)決定是否開啟自適應(yīng)哈希索引。
到此這篇關(guān)于MySQL數(shù)據(jù)庫(kù)自適應(yīng)哈希的文章就介紹到這了,更多相關(guān)MySQL自適應(yīng)哈希內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
mysql更新一個(gè)表里的字段等于另一個(gè)表某字段的值實(shí)例
下面小編就為大家?guī)?lái)一篇mysql更新一個(gè)表里的字段等于另一個(gè)表某字段的值實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-03-03
MySQL使用show status查看MySQL服務(wù)器狀態(tài)信息
這篇文章主要介紹了MySQL使用show status查看MySQL服務(wù)器狀態(tài)信息,需要的朋友可以參考下2017-01-01
CentOS6.9+Mysql5.7.18源碼安裝詳細(xì)教程
CentOS6.9+Mysql5.7.18源碼安裝,以下操作均在root用戶下執(zhí)行。下面通過(guò)本教程給大家詳細(xì)介紹CentOS6.9+Mysql5.7.18源碼安裝方法,需要的的朋友參考下吧2017-06-06

