这篇博文将讨论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/