摘要:本期圖解我們為大家解析一下是如何構建的。因此建立的第一關就是只為頻繁使用的索引樹建立。關卡該索引樹上的某個檢索條件要被經常使用顯而易見,如果我們為了一個很少出現的檢索條件建立,肯定是入不敷出的。
Adaptive Hash Index(以下簡稱 AHI)估計是 MySQL 的各大特性中,大家都知道名字但最說不清原理的一個特性。本期圖解我們為大家解析一下 AHI 是如何構建的。
首先我們思考一下 AHI 是為了解決什么問題:
隨著 MySQL 單表數據量增大,(盡管 B+ 樹算法極好地控制了樹的層數)索引 B+ 樹的層數會逐漸增多;
隨著索引樹層數增多,檢索某一個數據頁需要沿著 B+ 樹從上往下逐層定位,時間成本就會上升;
為解決檢索成本問題,MySQL 就想到使用某一種緩存結構:根據某個檢索條件,直接查詢到對應的數據頁,跳過逐層定位的步驟。這種緩存結構就是 AHI。
AHI 在實現上就是一個哈希表:從某個檢索條件到某個數據頁的哈希表,仿佛并不復雜,但其中的關竅在于哈希表不能太大(哈希表維護本身就有成本,哈希表太大則成本會高于收益),又不能太?。ㄌt緩存命中率太低,沒有任何收益)。
這就是 AHI(中文名:自適應哈希索引)中"自適應"的用途:建立一個"不大不小剛剛好"的哈希表。
本文主要討論 MySQL 是如何建立起一個"剛剛好"的 AHI 的,如圖 1 所示:需要經歷三個關卡,才能為某個數據頁建立 AHI,之后的查詢才能使用到該 AHI。
我們逐個關卡來介紹:
AHI 是為某個索引樹建立的(當該索引樹層數過多時,AHI 才能發揮效用)。如果某索引只被使用一兩次,就為之建立 AHI,會導致 AHI 太多,維護成本高于收益。
因此建立 AHI 的第一關就是:只為頻繁使用的索引樹建立 AHI。
顯而易見,如果我們為了一個很少出現的檢索條件建立 AHI,肯定是入不敷出的。
在此我們插播一個新概念 hash info,hash info 是用來描述一次檢索的條件與索引匹配程度(即此次檢索是如何使用索引的)。建立AHI時,就可以根據匹配程度,抽取數據中匹配的部分,作為 AHI 的鍵。
關卡 2 就是為了找到經常使用的 hash info。hash info 包括以下三項:
檢索條件與索引匹配的列數
第一個不匹配的列中,兩者匹配的字節數
匹配的方向是否從左往右進行
我們通過一個例子來簡要介紹 hash info 中第一項。假設一張表 table1,其索引是(A1 A2)兩列構成的索引:
如果檢索條件是(A1=1 and A2=1),那么此次檢索使用了該索引的最左兩列,hash info 就是(20true)
如果檢索條件是(A1=1) 那么此次檢索使用了該索引的最左一列,hash info 就是(10true)
關卡 2 就是為了找出經常使用的 hash info,作為建立 AHI 的依據。
如果我們為表中所有數據建立 AHI,那 AHI 就失去了緩存的意義:內存已不足以存放其身軀,必然要放到磁盤上,那么其成本顯然已經不低于收益。
回憶一下,AHI 是為了縮短 B+ 樹的查詢成本設計的,如果把自己再放到磁盤上,就得變成另一顆 B+ 樹(B+ 樹算法是處理磁盤查詢的高效結構),如此循環往復,嗚呼哀哉。
因此我們只能為表中經常被查詢的部分數據建立 AHI。所以關卡 3 的任務就是找出哪些數據頁是經常被使用的數據頁。
終于可以開始建立 AHI 了 我們舉個例子說明如何建立 AHI。假設以上三個關卡的通關情況如下:
表 table1 具有 4 列:A1A2A3B1。具有兩個索引 Idx1(A1A2A3) 和 Idx2(B1)
關卡 1:選出的索引是 Idx1
關卡 2:選出的 hash info 是 (2 0 true) (很多查詢命中了 Idx1 的最左兩列)
關卡 3:選出了某個數據頁 P3,其中包含數據 (1111) 和 (1222) 等等
那么建立 AHI 的過程是:在內存中,為數據頁 P3 中的每一行數據建立索引
對于數據(1111),根據 hash info,選取前兩列建立 AHI 的一項:(11)的哈希值->P3
對于數據(1222),根據 hash info,選取前兩列建立 AHI 的一項:(12)的哈希值->P3
以此類推
我們終于可以 AHI 加速查詢了,假設查詢條件是 A1=1 and A2=2,其滿足條件:
命中了索引 Idx1
索引 Idx1 上的 hash info 是(2 0 true),查詢條件(A1=1 and A2=2)根據 hash info 轉成(12)的哈希值
根據此哈希值在 AHI 中查詢,可查詢到數據頁為 P3
從以上過程可以看出,如果命中了 AHI,就可以跳過圖 2 中查詢索引樹的 4 個步驟,一次到位找到數據頁,提升性能。
我們回顧一下 MySQL 建立 AHI 的整個過程:
隨著數據量增大,索引樹變得越來越高,查詢數據頁成本變大
MySQL 引入 AHI 作為查詢數據頁的緩存,想降低查詢數據頁的成本
AHI 的"自適應"想解決的問題是 緩存不能太大,也不能太小
AHI 建立的過程中,通過不斷限制條件,只為經常使用的索引和經常使用的數據頁建立緩存
理解了 AHI 的建立過程,在運維過程中就更容易理解 AHI 的狀態,我們簡要盤點一下 AHI 的運維:
innodb_adaptive_hash_index_parts。凡是緩存都會涉及多個緩存消費者間的鎖競爭。MySQL 通過設立多個 AHI 分區,每個分區使用獨立的鎖,來減少鎖競爭。
SHOW ENGINE INNODB STATUS。其中有 AHI 的每個分區的使用率和 AHI 的命中率。如果你的業務 AHI 使用率過低,理解了 AHI 建立的原理后,就可以分析該業務為何不命中 AHI,來判斷業務是否合理,是否需要改變訪問模式或者將數據冷熱隔離。也可以考慮關閉 AHI,減少 AHI 的維護成本。
在低版本 MySQL 上使用 AHI,先查閱 MySQL bug 列表。低版本是存在一些與 AHI 相關的影響業務的缺陷,在新版本上均已修復,新版本 MySQL 可放心使用。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/126050.html
摘要:接下來我們要配置這個的端口,這樣他們才能運行時端口號不沖突。問題指明不同的端口號訪問也太蠢了吧的確很蠢,所以我們要慢慢過渡學習。接下來我們學習用來進行反向代理。阿里云的部分有一些配置的具體過程。 一、在linux上部署運行多個tomcat 1、以前的我們 雖然說是在linux上,但是windows上也是同樣的道理,只不過我們服務器都是選用linux罷了。 原先,自己有多個項目需要部署在...
摘要:不同于個人面經,這份面經具有普適性。我在前面的文章中也提到了應該怎么做自我介紹與項目介紹,詳情可以查看這篇文章備戰春招秋招系列初出茅廬的程序員該如何準備面試。是建立連接時使用的握手信號。它表示確認發來的數據已經接受無誤。 showImg(https://segmentfault.com/img/remote/1460000016972448?w=921&h=532); 該文已加入開源文...
閱讀 3528·2023-04-25 20:09
閱讀 3733·2022-06-28 19:00
閱讀 3053·2022-06-28 19:00
閱讀 3071·2022-06-28 19:00
閱讀 3160·2022-06-28 19:00
閱讀 2870·2022-06-28 19:00
閱讀 3031·2022-06-28 19:00
閱讀 2628·2022-06-28 19:00