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

在说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缓冲区

写到这里,大家可能有点迷糊了,既然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。

上述例子讲的是主键索引,普通的二级索引的情况呢,假设主键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速度。

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

  1. MySQL 单表百万数据记录分页性能优化

      来源:一颗卤蛋 链接:http://www.cnblogs.com/lyroge/p/3837886.html 背景: 自己的一个网站,由于单表的数据记录高达了一百万条,造成数据访问很慢,Goog ...

  2. mysql为何500w拆表_【mysql】MySQL 单表500W+数据,查询超时,如何优化呢?

    1.问题描述: MySQL 数据库,单表 `im_data_record`,查询超时(30s) 表结构如下图: 表索引如下图: 查询语句如下: SELECT `record_global_id`, ` ...

  3. mysql查询单表的销售额_MYsql数据库单表百万数据量查询

    最近总在意自己的网页刷新数据的速度,mysql5.7和mysql8.0单表数据库导入百万甚至千万数据的时候,会不会卡死,会不会慢? 因此编写测试用例,通过Navicat Premium来查询单表的时间 ...

  4. mysql 单表多字段查询_单表多字段MySQL模糊查询的实现

    MySQL模糊查询是我们经常会遇到的,下面就为您介绍MySQL模糊查询的实现方法,希望对您学习MySQL模糊查询方面能够有所帮助. 在最近的一个项目需要实现在单表中对多字段进行多个关键字的MySQL模 ...

  5. Mysql查看表的数据量

    1. 查看所有表信息 SELECT* FROMinformation_schema.TABLES WHERETABLE_SCHEMA = '库名'; 2. 查看各个表数据量 SELECTtable_n ...

  6. mysql单表多租户架构_多租户系统架构

    多租户系统架构 一种多租户系统架构 背景: 去年的时候,因为某些特殊原因,有幸带了一个组,参与了B2B平台的开发.说是B2B平台,因为这套程序开发完了后,可以拿给多个客户使用.客户可以搭建一套具有京东 ...

  7. mysql联表查询多记录显示_数据库:MySQL(多表的表记录的查询)(三)

    一.外键约束 1.创建外键 ---每一个班主任会对应多个学生 , 而每个学生只能对应一个班主任----主表 CREATE TABLE ClassCharger( id TINYINT PRIMARY ...

  8. mysql将备份的数据导入_成功将MySQL的大型数据导入导出和备份(转载)

    原来的数据使用的是MySQL4.1,大概有800M左右.使用 mysqldump -u username -p dbname > "filename" 导出的时候很容易死掉, ...

  9. mysql单表查询实验心得_5000字总结MySQL单表查询,新手看这一篇足够了!

    4.过滤 工作用的数据库表中一般包含大量数据,很少会一次全部查询,所以会使用where子句加过滤条件来查询我们需要的数据. 认识操作符 比较操作符 =(等于),<>.!=(不等于),=(大 ...

最新文章

  1. VMware HA环境搭建七:WIN2012 ISCSI目标服务器的安装
  2. 阿里程序员推荐的15 款常用开发者工具
  3. python while 循环 if elif else 判断
  4. Dubbo支持的协议
  5. ThoughtWorks洞见领域驱动设计思维导图笔记
  6. java 1.8环境变量_java1.8安装及环境变量配置教程
  7. 基于JAVA+SpringMVC+Mybatis+MYSQL的高校大学生社团招新管理系统
  8. 为什么前端工程师的工作很难找?
  9. extjs4 冻结列_extjs4 事件处理
  10. IK Analyzer 和 lucene结合使用
  11. TCP如何保障可靠性
  12. 谷粒商城:05. 分布式组件SpringCloud Alibaba
  13. 中国产品在越南如何落地?
  14. freeswitch被外国IP攻击盗打的防护措施
  15. 如何制作PE盘和系统启动盘
  16. 计算机原理(3)主板上的CPU,存储器,南桥北桥等的总结
  17. linux下安装xamp
  18. lpl夏季赛2021赛程表出炉,用当贝投影F3百吋大屏看比赛!
  19. html5采集手写签名,前端canvas手写签名(含移动端)
  20. expdp报错ORA-39002: invalid operation,ORA-39070: Unable to open the log file

热门文章

  1. 如何修改Ubuntu Linux的时间
  2. C# Hook原理及EasyHook简易教程
  3. MyBatis框架——mybatis插入数据返回主键(mysql、oracle)
  4. DIV层+CSS实现锁屏
  5. SQLserver分页 高效率
  6. ubuntu18.04安装python的mysqlclient==1.4.6报错ERROR Command errored out with exit status 1python setup
  7. CSDN产品公告:APP新增大厂在线刷题功能、博主排名规则更新、MD编辑器优化
  8. mysql从innodb转到MyIsam的count查询效率极大提升
  9. Mysql水平分表-merge
  10. PHP分页的limit与offset