mysql单表最大数据量_你的Mysql库真需要Adaptive Hash Index

说起AHI(Adaptive Hash Index),有的同学估计很陌生,都没听说,没关系,下面我会详细解释说明的,AHI是什么,mysql库为什么要设计AHI,解决什么问题,只有了解这些原理之后,才能判断,你的业务库是否需要AHI。

577d3551bf19dab30683cf32d0d50e62.png

在说AHI之前,先给大家提一下B+tree索引层数的问题,我们都是知道,随着MySQL数据库单表数据量越来越多(在这里留一个问题,多少数据量,才会导致B+tree层数增加呢?),B+tree的层数会逐渐增高。

当数据层数增加,索引检索时,从根节点到叶子节点的时间成本就会变大,这是因为需要搜索更多的枝节点。

这个时候,Mysql数据库的设计者,就考虑用一种技术去解决检索成本的问题,使用一种缓存结构,使用检索条件,可以直接查询需要的叶子节点数据,而不用逐层的搜索,跳过枝节点。这个缓存结构就是AHI,也就是自适应哈希索引(Adaptive Hash Index)。

在mysql数据库中AHI默认是开启的,并且占用buffer pool大小的1/16

[root@localhost] 14:11:04 [(none)]>show variables like '%innodb_adaptive_hash_index%';+----------------------------------+-------+| Variable_name                    | Value |+----------------------------------+-------+| innodb_adaptive_hash_index       | ON    || innodb_adaptive_hash_index_parts | 8     |+----------------------------------+-------+2 rows in set (0.00 sec)

AHI是可以在线关闭的,执行以下命令就可以关闭了

[root@localhost] 14:16:47 [(none)]>set global innodb_adaptive_hash_index=off;Query OK, 0 rows affected (0.00 sec)[root@localhost] 14:16:57 [(none)]>show variables like '%innodb_adaptive_hash_index%';+----------------------------------+-------+| Variable_name                    | Value |+----------------------------------+-------+| innodb_adaptive_hash_index       | OFF   || innodb_adaptive_hash_index_parts | 8     |+----------------------------------+-------+2 rows in set (0.00 sec)

而且不是B+tree索引树上什么数据都能进入到AHI的,是需要满足一定条件才能被加载到AHI缓冲区

7c7924ee82c2c2bb3320727d218bc2f4.png

写到这里,大家可能有点迷糊了,既然AHI是为了提高索引查询效率,减少搜索时间的,为什么要关闭呢?

在这里大家回想一下,AHI解决的是什么问题,是因为B+tree索引层数高,导致索引搜索时间变成,那么这里就得想想,B+tree索引层数到底有多高,多少业务记录数才会到知道层数加1。

在MySQL中一个页大小为16Kb,这个是可以从参数里查看的

[root@localhost] 15:59:19 [(none)]>show variables like 'innodb_page_size';+------------------+-------+| Variable_name      | Value |+------------------+-------+| innodb_page_size | 16384 |+------------------+-------+1 row in set (0.00 sec)

如果业务表一条记录平均长度为1Kb,那么1个页,可以存放16条业务记录,假设主键ID为bigint类型,其长度为8个字节,在B+tree里,页面指针大小为6字节,这样枝节点和根节点,一条记录是14字节,那么一个页中能存放多少这样的记录呢,16384/14=1170,一颗高度为2的B+tree可以存放1170 * 16=18720条记录,如果高度为3,则可以存放1170 * 1170 * 16=21902400条记录,大约2000多万条记录,可以满足绝大多数单表记录条数了,如果是交易订单表超过,建议分表,保证单表记录数不超过500W,单表大小不超过10G。

1bd6124fed962f31db833019c680176d.png

上述例子讲的是主键索引,普通的二级索引的情况呢,假设主键ID为bigint类型,其长度为8个字节,二级索引为vachar类型,长度为10,那么索引叶子节点可以存放16384/48=341,在这里需要注意如果是utf8,则占用30字节,utf8mb4则占用40字节,假设二级索引10个长度全部写满,在utf8mb4情况下,页面指针大小6字节+二级索引列长度40,一个16k的非叶子节点页能存放16384/46=356条记录。
一颗高度为2的B+tree能存放的索引记录为:341 * 356 = 121396
一颗高度为3的B+tree能存放的索引记录为:341 * 356 * 356 = 43216976
可以看到大约能存放4000多万二级索引数据。

综上可以看出,生产上的B+tree的高度基本不会超过3,而能被加载到AHI缓冲区的数据也不会太多,除非是经常被索引查询的业务数据,而且现在数据库服务器开始大量使用SSD盘,随机读的速度也很快,可以考虑关闭AHI,将内存释放,还给buffer pool,同时,在做truncate table,drop table时,不用再清理AHI中清理要删除表的数据块,提高truncate table,drop table速度。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值