【MySQL】MySQL5.6新特性之Batched Key Access

一 介绍
  MySQL 5.6版本提供了很多性能优化的特性,其中之一是关于提高表join性能的算法 --- Batched Key Access (BKA) ,本文将结合之前写过MRR,BNL优化特性一起来详细介绍该算法。这篇文章是
我拖延时间最久的,之前一直没有搞清楚MRR,BKA之间的关联 ,BKA,BNL的区别,本周花了一天时间收集资料,算是搞懂了,里面有基于文档翻译的,可能不准确,请大家指正。

二 原理

  对于多表join语句,当MySQL使用索引访问第二个join表的时候,使用一个join buffer来收集第一个操作对象生成的相关列值。BKA构建好key后,批量传给引擎层做索引
查找。key是通过MRR接口
提交给引擎的. 这样,MRR使得查询更有效率。 

大致的过程如下:


1 BKA使用join buffer保存由join的第一个操作产生的符合条件的数据。
 
2 然后BKA算法构建key来访问被连接的表,并批量使用MRR接口提交keys到数据库存储引擎去查找查找。

3 提交keys之后,MRR使用最佳的方式来获取行并反馈给BKA . 

BKA使用join buffer size来确定buffer的大小,buffer越大,访问被join的表/内部表就越顺序。
MRR接口有2个应用场景:
场景1:应用于传统的基于磁盘的存储引擎(innodb,myisam),对于这些引擎join buffer中keys是一次性提交到MRR,MRR通过key找到rowid,通过rowid来获取数据
场景2:应用于远程存储引擎(NDB),来自join buffer上的部分key,从SQL NODE发送到DATA NODE,然后SQL NODE会收到通过相关关系匹配的行组合。然后使用这些行组合匹配出新行。然后在发送新
key,直到发完为止。


三 BNL和BKA,MRR的关系
  BNL和BKA都是批量的提交一部分结果集给下一个被join的表(标记为T),从而减少访问表T的次数,那么它们有什么区别呢?NBL和BKA的思想是类似的,详情见:《nest-loop-join官方手册》
 第一 NBL比BKA出现的早,BKA直到5.6才出现,而NBL至少在5.1里面就存在。
 第二 NBL主要用于当被join的表上无索引,Join buffering can be used when the join is of type ALL or index (in other words, when no possible keys can be used, and a full
scan is done, of either the data or index rows, respectively)

 第三 BKA主要是指在被join表上有索引可以利用,那么就在行提交给被join的表之前,对这些行按照索引字段进行排序,因此减少了随机IO,排序这才是两者最大的区别,但是如果被join的表没用
索引呢?那就使用NBL了。

 上面原理环境提到讲了在BKA实现的过程中就是通过传递keys给MRR接口,本质上还是在MRR里面实现,下面这幅图则展示了它们之间的关系:
 

四 如何使用
  要使用BKA,必须调整系统参数optimizer_switch的值,batched_key_access设置为on,因为BKA使用了MRR,因此也要打开MRR,但是基于成本优化MRR算法不是特别准确官方文档推荐关闭
mrr_cost_based,将其设置为off。


set optimizer_switch='mrr=on,mrr_cost_based=off,batched_key_access=on' 

 另外多表join语句 ,被join的表/非驱动表必须索引可用。

五 参考资料
[1].Block Nested-Loop and Batched Key Access Joins
[3].Block-Based Join Algorithms
[4].Join Optimizations in MySQL 5.6 and MariaDB 5.5 
[5].bacthed-key-access-speeds-up-disk-bound 
[6].Multi Range Read Optimization 
[7].On the multi range read&batch key access&block nested loop


MySQL 5.7 和 5.8 之间的版本变化主要集中在性能优化、功能增强以及内部架构改进等方面,尽管两者之间的变化幅度相对较小,但依然在多个关键领域引入了新特性或优化手段。以下是两者之间的主要特性差异和版本对比: ### 查询性能优化 在 MySQL 5.8 中,查询优化器得到了进一步增强,引入了基于成本的优化器改进,提高了复杂查询的执行效率。此外,还增加了对并行查询执行的支持,使得多线程查询在多核系统上能够更高效地运行,从而显著提升查询响应速度。 ### JSON 数据类型处理 MySQL 5.8 在 JSON 数据类型处理方面进行了优化,引入了 JSON 表达式索引功能,使得基于 JSON 字段的查询效率进一步提升。这一改进使得 JSON 类型的数据在存储和检索时更加高效,增强了数据库对现代应用中非结构化数据的支持能力。 ### 事务日志优化 在事务处理方面,MySQL 5.8 对 redo log 和 undo log 的管理机制进行了优化,提升了事务提交的性能。这一改进使得数据库在高并发环境下能够更稳定地处理大量事务操作,减少了日志写入的瓶颈。 ### 隐藏索引功能 MySQL 5.8 引入了隐藏索引(Invisible Index)的功能,允许将某个索引设置为不可见状态,从而让查询优化器忽略该索引的存在。这一特性在性能调优过程中非常有用,可以临时禁用索引并观察其对查询性能的影响,进而判断索引的实际价值。 ### 数据字典改进 MySQL 5.8 继续优化了数据字典的设计,进一步提升了元数据的存储效率和访问性能。这一改进使得数据库在处理大规模元数据时更加高效,降低了系统资源的消耗。 ### 持久化配置更改 MySQL 5.8 支持通过 `SET PERSIST` 命令修改全局配置参数,并将这些更改持久化保存到配置文件中。例如,执行 `SET PERSIST max_connections = 500;` 后,该设置将在数据库重启后仍然生效,提升了配置管理的灵活性和稳定性。 ### 多范围读取(MRR)与批量键访问(BKA) MySQL 5.8 在存储引擎层面引入了更高效的查询优化技术,如 Multi-Range Read(MRR)和 Batched Key Access(BKA)。这些技术通过将随机 I/O 转换为顺序 I/O,显著提升了基于索引的大范围查询性能,减少了磁盘访问的开销。 ### 示例代码:使用隐藏索引 ```sql -- 创建一个隐藏索引 CREATE INDEX idx_hidden ON employees(name) INVISIBLE; -- 查看索引状态 SHOW INDEX FROM employees; -- 恢复索引可见性 ALTER INDEX idx_hidden ON employees VISIBLE; ``` ### 示例代码:使用 SET PERSIST 修改配置 ```sql -- 设置最大连接数并持久化 SET PERSIST max_connections = 500; -- 查看当前配置值 SHOW VARIABLES LIKE 'max_connections'; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值