在MySQL中,Batched Key Access (BKA) Join algorithm该算法用于对联接表和连接缓冲区的索引访问。BKA算法支持内连接,外连接和半连接操作,包括嵌套外连接。BKA的优点包括由于更高效的表扫描而提高了连接性能。此外,先前仅用于内连接的块嵌套循环(BNL)连接算法已扩展,可用于外连接和半连接操作,包括嵌套外连接。
以下部分讨论了连接缓冲区管理,它是原始BNL算法扩展,扩展BNL算法和BKA算法的基础。
MySQL可以使用连接缓冲区不仅可以执行内部联接而无需对内部表进行索引访问,还可以执行子查询展平后出现的外部联接和半联接。此外,当存在对内部表的索引访问时,可以有效地使用连接缓冲区。
当存储感兴趣的行列的值时,连接缓冲区管理代码更有效地利用连接缓冲区:如果行的值为NULL,则不在缓冲区中为行列分配额外字节,并且对varchar类型的每一个值分配最小的字节。
他定义了两种类型的缓冲区:常规缓冲区和增量缓冲区。假设表t1与t2连接的时候使用连接缓冲区B1,然后他们的结果与表t3连接使用连接缓冲区B2:
增量连接缓冲区始终相对于早期连接操作的连接缓冲区是增量的,因此第一个连接操作的缓冲区始终是常规缓冲区。在刚刚给出的实例中,缓冲B1 用来连接表t1和 t2必须是常规缓冲区。
增量缓冲区用于一个连接操作中包含被连接的表中的一行当中他感兴趣的列。有第一个连接产生的表中的匹配的行中它感兴趣的列进行扩充。增量缓冲区中的若干行可以引用同一行r,只要所有这些行都匹配行r,则该行r的列存储在先前的连接缓冲区中。
增量缓冲区可以减少从先前连接操作使用的缓冲区中复制列的频率。这节省了缓冲区空间,因为在一般情况下,第一个连接操作数产生的行可以由第二个连接操作数产生的几个行匹配。不必从第一个操作数生成一行的多个副本。由于复制时间的减少,增量缓冲区还可以节省处理时间。
系统变量 的block_nested_loop和 batched_key_access标志 optimizer_switch控制优化器如何使用块嵌套循环和批量密钥访问连接算法。
MySQL BNL算法的原始实现被扩展为支持外连接和半连接操作。
当使用连接缓冲区执行这些操作时,每个放入缓冲区的行都会提供一个匹配标志。
如果使用连接缓冲区执行外连接操作,则检查第二个操作数生成的表的每一行是否与连接缓冲区中的每一行匹配。找到匹配项后,将形成一个新的扩展行(原始行加上第二个操作数中的列),并通过其余的连接操作发送以进一步扩展。此外,启用缓冲区中匹配行的匹配标志。在检查了要连接的表的所有行之后,将扫描连接缓冲区。缓冲区中没有启用匹配标志的每一行都由NULL补充扩展(NULL 第二个操作数中每列的值),并由剩余的连接操作发送以进一步扩展。
系统变量 的block_nested_loop标志 optimizer_switch控制优化器如何使用块嵌套循环算法。
在EXPLAIN输出时,使用BNL时Extra中会包含Using join buffer (Block Nested Loop),type的值是ALL, index,或 range。
MySQL实现了一种连接表的方法,叫做Batched Key Access(BKA),当存在对第二个连接操作数生成的表的索引访问时,可以应用BKA。像BNL算法一样,BKA算法采用连接缓冲区积累由连接操作产生的第一个的行中的感兴趣的列。然后BKA算法建立KEY到表的访问在缓冲区中连接所有行,,并将这些KEY批量提交到数据库引擎以进行索引查找。在提交key之后,MRR引擎函数以最佳方式在索引中执行查找,获取由这些密钥找到的连接表的行,并开始向匹配行提供BKA连接算法。每个匹配行与对连接缓冲区中的行的引用相耦合。
使用BKA时,值join_buffer_size定义了每个请求到存储引擎的批量密钥的大小。缓冲区越大,对连接操作的右侧表的顺序访问就越多,这可以显着提高性能。
要使用BKA,必须将系统变量的batched_key_access标志 optimizer_switch设置为on。BKA使用MRR,因此mrr标志也必须是 on。目前,MRR的成本估算过于悲观。因此,也有必要对 mrr_cost_based要 off用于要使用的BKA。以下设置启用BKA:
mysql> SET optimizer_switch='mrr=on,mrr_cost_based=off,batched_key_access=on';
MRR功能有两种执行方式:
对于第一种情况,保留一部分连接缓冲区以存储由索引查找选择的行ID(主键),并作为参数传递给MRR功能。
没有特殊的缓冲区来存储为连接缓冲区中的行构建的密钥。相反,为缓冲区中的下一行构建键的函数作为参数传递给MRR函数。
在EXPLAIN输出中,使用BKA时Extra显示的值是Using join buffer (Batched Key Access),type的值是 ref或者eq_ref.
除了使用 optimizer_switch系统变量控制优化器在会话范围内使用BNL和BKA算法之外,MySQL还支持优化器提示以基于每个语句影响优化器。