這篇博文將討論InnoDB中的自適應哈希索引的用途,以及它是否適合你的工作負載。
AHI概述
Adaptive Hash Index (AHI)是InnoDB中最難理解的特性之一。理論上,它會神奇地決定什么時候值得用快速哈希查找表來補充基于InnoDB b - tree的索引,然后在沒有用戶提示的情況下自動構建它們。
由于AHI被認為是“像魔術一樣”工作的,它只有很少的配置可用。在早期版本中,根本沒有可用的配置選項。之后的版本添加了innodb_adaptive_hash_index來禁用AHI(可以設置為0或OFF)。MySQL 5.7通過啟用innodb_adaptive_hash_index_parts增加了對AHI分區的能力。(僅供參考,該特性在Percona Server中從5.5版本起就以innodb_adaptive_hash_index_partitions的形式存在了。)
要理解AHI對性能的影響,可以把它當作一個緩存來考慮。如果發生了一個AHI“Hit”,我們有更好的查找性能;如果是一個AHI " Miss ",那么性能會稍微變差一些(因為檢查哈希表的匹配速度很快,但不是免費的)。
這并不是等式的唯一部分。除了查找的成本之外,還有AHI維護的成本。我們可以比較維護成本(從添加和刪除AHI的行數可以看出)和成功查找的成本。較高的比率意味著以較低的成本加快了許多查找。低比例意味著相反的情況:我們可能付出了太多的維護成本,卻沒有得到什么好處。
最后,添加額外的爭用還需要付出代價。如果您的工作負載包含對大量索引或表的查找,您可以通過適當設置innodb_adaptive_hash_index_parts來減少影響。但是,如果存在熱索引,那么AHI可能會成為高并發性的瓶頸,可能需要禁用。
AHI對工作負載是否適用
為了確定AHI是否可能幫助我的工作負載,我們應該驗證AHI命中和成功查找對維護操作的比率盡可能高。
讓我們研究一下對于一些簡單的工作負載實際會發生什么。我將根據主鍵使用基本的Sysbench Lookup—這是最簡單的工作負載。我們會發現,即使在這種情況下,我們也會發現一些行為。
對于這個測試,我使用帶有16GB緩沖池的MySQL 5.7.11。sysbench的基本命令行是:
sysbench ‐‐test=/usr/share/doc/sysbench/tests/db/select.lua ‐‐report‐in terval=1 ‐‐oltp‐table‐size=1 ‐‐max‐time=0 ‐‐oltp‐read‐only=off ‐‐max‐reques ts=0 ‐‐num‐threads=1
‐‐rand‐type=uniform ‐‐db‐driver=mysql ‐‐mysql‐ password=password ‐‐mysql‐db=test_innodb run表中有1行數據測試
注意oltp-table-size=1;這不是一個錯誤,但測試了AHI在一個非常基本的情況下的行為:

而且它工作得很完美:100%的命中率,而且沒有AHI維護操作。
表中有10000行測試
當我們將OLTP表設置為OLTP -table-size=10000時,我們得到如下圖:


同樣,我們幾乎看不到頭頂。有一個罕見的事件是16行左右添加到AHI(可能是由于AHI哈希沖突)。除此之外,它幾乎是完美的。
表中有10M行測試
如果我們將oltp-table-size設置為10000000,我們現在有更多的數據(但仍然比緩沖池大小小得多):


在這種情況下,在接近100%命中率之前,顯然有一個熱身期——它從來沒有完全達到100%(即使在較長的運行之后)。在這種情況下,維護操作似乎沒有顯示出漸近接近零的跡象。我的看法是,如果有10M行,那么哈希沖突的幾率會更高,從而導致更多的AHI重建。
表中500M行測試
現在我們將OLTP表的大小設置為:OLTP -table-size=500000000。這將使數據的大小超過Innodb緩沖池的大小。


在這里,我們看到很多緩沖池失誤,導致非常糟糕的AHI命中率(從未達到1%)。我們還可以看到從AHI中添加/刪除數萬行的巨大開銷。顯然,在這種情況下,AHI并沒有增加任何價值
表中500M行測試且pareto
最后,讓我們使用設置oltp-table-size=500000000,并添加——rand-type=pareto。——rand-type=pareto設置支持傾斜分布,這是許多現實生活中的數據訪問模式的更典型的場景


在這種情況下,我們看到AHI命中率逐漸提高,接近50%。AHI維護開銷正在下降,但從來沒有達到值得的程度。
值得注意的是,在上述兩種情況下,AHI還沒有達到“穩定狀態”。穩態條件顯示添加和刪除的行數接近相等。
從上面的工作負載中你可以看到,InnoDB中的自適應哈希索引“魔法”并不總是發生!在某些情況下,AHI確實很有幫助,而在其他情況下,AHI增加了大量的數據結構維護開銷,并從緩沖池中拿走了內存——更不用說爭用開銷了。在這些情況下,最好禁用AHI。
不幸的是,AHI似乎沒有內置的邏輯來檢測是否有太多的“波動”在進行,從而使得維護AHI是值得的。
我建議使用這些數字作為一般指南,以確定AHI是否可能有利于您的工作負載。確保運行測試/基準來確定。
原文標題:Is Adaptive Hash Index in InnoDB right for my workload?
原文作者:Peter Zaitsev
原文地址:https://www.percona.com/blog/2016/04/12/is-adaptive-hash-index-in-innodb-right-for-my-workload/




