您现在的位置是:主页 > news > 做网站网页维护手机App开发/谷歌seo新规则
做网站网页维护手机App开发/谷歌seo新规则
admin2025/5/4 20:08:45【news】
简介做网站网页维护手机App开发,谷歌seo新规则,企业门户网站建设思路,手机h5网站Adaptive Hash Index (以下简称AHI) 估计是 MySQL 的各大特性中,大家都知道名字但最说不清原理的一个特性。本期图解我们为大家解析一下AHI是如何构建的。 首先我们思考一下AHI是为了解决什么问题: 随着MySQL单表数据量增大,(尽管…
Adaptive Hash Index (以下简称AHI) 估计是 MySQL 的各大特性中,大家都知道名字但最说不清原理的一个特性。本期图解我们为大家解析一下AHI是如何构建的。
首先我们思考一下AHI是为了解决什么问题:
-
随着MySQL单表数据量增大,(尽管B+树算法极好地控制了树的层数)索引B+树的层数会逐渐增多;
-
随着索引树层数增多,检索某一个数据页需要沿着B+树从上往下逐层定位,时间成本就会上升;
-
为解决检索成本问题,MySQL就想到使用某一种缓存结构:根据某个检索条件,直接查询到对应的数据页,跳过逐层定位的步骤。这种缓存结构就是AHI。
AHI在实现上就是一个哈希表:从某个检索条件到某个数据页的哈希表,仿佛并不复杂,但其中的关窍在于哈希表不能太大(哈希表维护本身就有成本,哈希表太大则成本会高于收益),又不能太小(太小则缓存命中率太低,没有任何收益)。
这就是AHI(中文名:自适应哈希索引)中"自适应"的用途:建立一个"不大不小刚刚好"的哈希表。
本文主要讨论MySQL是如何建立起一个"刚刚好"的AHI的,如图1所示:需要经历三个关卡,才能为某个数据页建立AHI,之后的查询才能使用到该AHI。
我们逐个关卡来介绍:
关卡1:某个索引树要被使用足够多次
AHI是为某个索引树建立的(当该索引树层数过多时,AHI才能发挥效用)。如果某索引只被使用一两次,就为之建立AHI,会导致AHI太多,维护成本高于收益。
因此建立AHI的第一关就是:只为频繁使用的索引树建立AHI。
关卡2:该索引树上的某个检索条件要被经常使用
显而易见,如果我们为了一个很少出现的检索条件建立AHI,肯定是入不敷出的。
在此我们插播一个新概念hash info,hash info是用来描述一次检索的条件与索引匹配程度(即此次检索是如何使用索引的)。建立AHI时,就可以根据匹配程度,抽取数据中匹配的部分,作为AHI的键。
关卡2就是为了找到经常使用的hash info。hash info 包括以下三项:
-
检索条件与索引匹配的列数
-
第一个不匹配的列中,两者匹配的字节数
-
匹配的方向是否从左往右进行
我们通过一个例子来简要介绍hash info中第一项。假设一张表table1,其索引是(A1, A2)两列构成的索引:
-
如果检索条件是(A1=1 and A2=1),那么此次检索使用了该索引的最左两列,hash info就是(2,0,true)
-
如果检索条件是(A1=1), 那么此次检索使用了该索引的最左一列,hash info就是(1,0,true)
关卡2就是为了找出经常使用的hash info,作为建立AHI的依据。
关卡3:该索引树上的某个数据页要被经常使用
如果我们为表中所有数据建立AHI,那AHI就失去了缓存的意义:内存已不足以存放其身躯,必然要放到磁盘上,那么其成本显然已经不低于收益。
回忆一下,AHI是为了缩短B+树的查询成本设计的,如果把自己再放到磁盘上,就得变成另一颗B+树(B+树算法是处理磁盘查询的高效结构),如此循环往复,呜呼哀哉。
因此我们只能为表中经常被查询的部分数据建立AHI。所以关卡3的任务就是找出哪些数据页是经常被使用的数据页。
修成正果:终于开始建立AHI
终于可以开始建立AHI了, 我们举个例子说明如何建立AHI。假设以上三个关卡的通关情况如下:
-
表table1具有4列:A1,A2,A3,B1。具有两个索引 Idx1(A1,A2,A3) 和 Idx2(B1)
-
关卡1:选出的索引是 Idx1
-
关卡2:选出的hash info是 (2, 0, true) (很多查询命中了Idx1的最左两列)
-
关卡3:选出了某个数据页P3, 其中包含数据 (1,1,1,1) 和 (1,2,2,2) 等等
那么建立AHI的过程是: 在内存中,为数据页P3中的每一行数据建立索引
-
对于数据(1,1,1,1),根据hash info,选取前两列建立AHI的一项:(1,1)的哈希值->P3
-
对于数据(1,2,2,2),根据hash info,选取前两列建立AHI的一项:(1,2)的哈希值->P3
-
以此类推
普度众生:终于可以使用AHI
我们终于可以AHI加速查询了,假设查询条件是A1=1 and A2=2,其满足条件:
-
命中了索引Idx1
-
索引Idx1上的hash info是(2, 0, true), 查询条件(A1=1 and A2=2)根据hash info转成(1,2)的哈希值
-
根据此哈希值在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可放心使用。