MySQL 8.0 官方文档 第八章 优化(十三)—— 块嵌套循环和批量键访问连接

第八章 优化(十三)—— 块嵌套循环和批量键访问连接

8.2 优化SQL语句

8.2.1 优化 SELECT 语句

8.2.1.12 块嵌套循环和批量键访问连接

在MySQL中,可以使用一种称为批量键访问(Batched Key Access --> BKA)的连接算法,该算法在连接表时同时使用索引访问和连接缓冲区。BKA算法支持内连接、外连接和半连接操作,包括嵌套的外连接。BKA的好处包括由于采用更高效的表扫描而提高了连接性能。此外,以前只能用于内连接的块嵌套循环(Block Nested-Loop --> BNL)连接算法也得到了扩展,现可以用于外连接和半连接操作,包括嵌套的外连接。

下面的章节将讨论连接缓冲区管理,它是原始BNL算法、扩展BNL算法和BKA算法的扩展基础。有关半连接策略的信息,请参见8.2.2.1节“用半连接转换优化IN和EXISTS子查询谓词”。

块嵌套循环和批量键访问算法使用到的连接缓冲区管理

MySQL不仅可以使用连接缓冲区来执行没有索引访问的内部表的内连接,还可以执行子查询完成后出现的外连接和半连接。此外,当可以利用索引访问内部表时,可以有效地使用连接缓冲区。

在存储感兴趣行中的列数值时,连接缓冲区管理代码能更有效地利用连接缓冲区空间:如果行中的列数值为NULL,则不会在缓冲区中为其分配额外的字节,并且为VARCHAR类型的任何值分配最小的字节数。

该代码支持两种类型的缓冲区:常规缓冲区和增量缓冲区。假设使用连接缓冲区B1来连接表 t1 和表 t2,并使用连接缓冲区B2将B1中已连接的行与表 t3 进行连接:

  • 常规连接缓冲区保存来自每个连接操作数中的列。如果B2是一个常规连接缓冲区,那么放入 B2 中的每一行 r 都是由 B1中一行 r1 中的列和表 t3 中能匹配的行 r2 中的感兴趣的列组合而成的。

  • 增量连接缓冲区只包含由第二个连接操作数产生的表中行中的列。也就是说,它是从第一个操作数缓冲区基础上递增的一行。如果B2是一个增量连接缓冲区,那么它包含了行 r2 中感兴趣的列以及对B1中行 r1 的链接。

增量连接缓冲区总是相对于前一个连接操作的连接缓冲区增量的,因此第一个连接操作的缓冲区总是常规缓冲区。在刚刚给出的示例中,用于连接表 t1 和 t2 的缓冲区B1必须是常规缓冲区。

用于连接操作的增量缓冲区中的每一行只包含要连接的表中一行感兴趣的列。这些列是通过引用第一个连接操作数生成的表中匹配行的感兴趣列来递增的。增量缓冲区中的多行可以引用同一行 r,只要所有这些行与行 r 匹配,而行 r 的列存储在前面的连接缓冲区中。

增量缓冲区使从前一个连接操作所用的缓冲区中复制列的频次降低。这一方面节省了缓冲区空间,因为,通常情况下,第一个连接操作数产生的一行可能与第二个连接操作数产生的多行匹配。另一方面由于不必对第一个操作数产生的行进行多次复制,从而减少了复制时间,所以使用增量缓冲区还节省了处理时间。

在MySQL 8.0中,系统变量optimizer_switch中的block_nested_loop(块嵌套循环)标记工作如下:

  • 在MySQL 8.0.20之前,它控制优化器如何使用块嵌套循环连接算法。
  • 在MySQL8.0.18及更高版本中,它还控制哈希连接的使用(请参阅第8.2.1.4节“哈希连接优化”)。
  • 从MySQL 8.0.20开始,这个标志只控制哈希连接,不再支持块嵌套循环算法。

batched_key_access(批量键访问)标志控制优化器如何使用批量键访问连接算法。

默认情况下,block_nested_loop是开启的,batched_key_access是关闭的。请参见8.9.2节,“可切换优化”。也可以应用优化器提示;请参阅块嵌套循环和批量键访问算法的优化提示。

有关半连接策略的信息,请参阅第8.2.2.1节“使用半连接转换优化IN和EXISTS子查询谓词”

外连接和半连接的块嵌套循环算法

MySQL BNL算法的最初实现已被扩展为支持外连接和半连接操作(后来被哈希算法取代;参见第8.2.1.4节“哈希连接优化”)。

当使用连接缓冲区执行这些操作时,将为放入缓冲区的每一行都提供一个匹配标志。

如果使用连接缓冲区执行外连接操作,则会检查第二个操作数生成的表中的每一行是否与连接缓冲区中的每一行相匹配。当找到匹配项时,将形成新的扩展行(原始行加上第二个操作数相应的列),并发送至其余的连接操作执行进一步的扩展。此外,缓冲区中匹配行的匹配标志设置为启用。在检查了要连接表中所有行之后,执行扫描连接缓冲区。对缓冲区中匹配标志的未设置为启用的每一行都扩展为空补行(第二个操作数中的每列的值都设置为NULL),并发送至其余的连接操作执行进一步的扩展。

在MySQL 8.0中,系统变量optimizer_switch的block_nested_loop(块嵌套循环)标记工作如下:

  • 在MySQL 8.0.20之前,它控制优化器如何使用块嵌套循环连接算法。

  • 在MySQL8.0.18及更高版本中,它还控制哈希连接的是否使用(请参阅第8.2.1.4节“哈希连接优化”)。

  • 从MySQL 8.0.20开始,这个标志只控制哈希连接,不再支持块嵌套循环算法。

有关更多信息,请参阅第8.9.2节“可切换优化”。优化器提示也可以应用;有关块嵌套循环和批量键访问算法,请参见优化器提示。

在EXPLAIN输出中,当Extra列的值包含Using join buffer(块嵌套循环),且type列的值为ALL、index或range时,表示对表使用了 BNL。

有关半连接策略的信息,请参阅第8.2.2.1节“使用半连接转换优化IN和EXISTS子查询谓词”

批量键范围连接

MySQL实现了一种称为批量键访问(BKA)连接算法的连接表方法。当第二个连接操作数生成的表有访问索引时,就可以应用BKA。与BNL连接算法一样,BKA连接算法使用连接缓冲区来累积在连接操作时第一个操作数生成的行中的感兴趣的列。然后,在缓冲区中BKA算法构建要被访问连接表中的所有行的键,并将这些键批量提交给数据库引擎用以索引查找。这些键通过多范围读(MRR)接口提交到引擎(见第8.2.1.11节“多范围读优化”)。在提交这些键后,MRR引擎函数以最佳方式在索引中执行查找,获取利用这些键找到连接表中的行,并开始向BKA连接算法提供匹配行。每个匹配行都与连接缓冲区中的行进行引用耦合。

当使用BKA时,join_buffer_size(连接缓冲区大小)的值定义了每次请求存储引擎时(译者:要发送的)批量键的大小。该缓冲区越大,一次对连接操作的右表进行的顺序访问就越多,这可以显著提高性能。

要使用BKA,必须把optimizer_switch系统变量的batched_key_access(批量键访问)标志设置为on。由于BKA需要使用MRR,所以MRR标志也必须是打开的。目前,MRR的成本估计过于悲观。因此,要使用BKA,也有必要关闭mrr_cost_based标志。以下设置启用BKA:

mysql> SET optimizer_switch='mrr=on,mrr_cost_based=off,batched_key_access=on';

MRR函数执行有两种场景:

  • 第一个场景用于传统的基于磁盘的存储引擎,如InnoDB和MyISAM。对于这些引擎,连接缓冲区中所有行的键通常都会立即提交到MRR接口。特定于引擎的MRR函数对提交的键执行索引查找,先从中得到行ID(或主键),然后根据BKA算法的请求逐个获取所有这些已选定行ID的行。每一行都会返回一个关联引用,该引用允许访问连接缓冲区中匹配的行。MRR函数以最佳方式获取这些行:它们以行ID(主键)顺序获取。因为数据是按磁盘顺序读取的,而不是按照随机顺序,所以提高了性能。

  • 第二种场景用于NDB等远程存储引擎。MySQL服务器(SQL节点)将连接缓冲区中部分行的键和其链接一起打包发送到MySQL集群数据节点。作为回报,SQL节点接收一个(或几个)匹配行和相应链接的包。BKA连接算法获取这些行并构建新连接的行。然后向数据节点发送一组新的键,并使用返回包中的行来构建新的连接行。该过程将继续,直到连接缓冲区中的最后一个键被发送到数据节点,并且SQL节点已接收并连接与这些键匹配的所有行。这提高了性能,因为SQL节点发送给数据节点的承载键的包更少,这意味着它与数据节点之间执行连接操作的往返次数更少。

在第一种情况下,会保留部分连接缓冲区来存储用于索引查找所选择的行ID(主键),并作为参数传递给MRR函数。

没有特殊的缓冲区来存储由连接缓冲区中的行构建的键。相反,为缓冲区中的下一行生成键的函数作为参数传递给MRR函数。

在EXPLAIN输出中,当Extra值包含Using join buffer (batch Key Access),且类型值为 ref 或 eq_ref 时,表示对表使用BKA。

块嵌套循环和批量键访问算法的优化器提示

除了使用optimizer_switch系统变量来控制会话范围内BNL和BKA算法的优化器使用之外,MySQL还支持优化器提示来影响每条语句的优化器。参见8.9.3节,“优化提示”。

想要使用BNL或BKA提示来启用外连接中的任何内部表的连接缓冲,必须为该外连接中的所有内部表都启用连接缓冲。

上一集 MySQL 8.0 官方文档 第八章 优化(十二)—— 多范围读优化

下一集 MySQL 8.0 官方文档 第八章 优化(十四)—— 条件过滤

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: MySQL官方文档MySQL数据库管理系统的官方参考指南,提供了全面而详细的文档资源,旨在帮助用户了解和使用MySQL数据库。MySQL 8.0官方文档中也提供了中文版,方便中国用户阅读和查找所需的信息。 MySQL 8.0官方文档中文版内容包括了MySQL数据库的各个方面,涵盖了安装、配置、使用、维护和开发等各个方面的知识。文档以清晰的结构组织,使用简单明了的语言描述概念和操作步骤,易于理解和学习。 该中文版文档包括了以下主要内容: 1. 概述:介绍MySQL数据库和其特点,以及MySQL 8.0的新功能和改进。 2. 安装和配置:讲解了如何下载、安装和配置MySQL数据库的步骤和指南。 3. 使用MySQL:包括了数据库的基本操作,如创建和管理表、插入和查询数据、更新和删除数据等。 4. 数据库管理:介绍了如何管理MySQL数据库,包括用户和权限管理、备份和还原数据库、性能优化等。 5. 高级主题:涵盖了高级技术主题,如存储过程、触发器、视图、复制和集群等。 6. 开发者指南:提供了MySQL数据库的开发者指南,包括了MySQL语法、数据类型和连接器等。 通过阅读MySQL 8.0官方文档中文版,用户可以轻松学习和掌握MySQL数据库,从基础操作到高级技术都可以找到相应的信息。并且,文档还提供了示例代码和实用的技巧,帮助用户更好地使用和优化MySQL数据库。 总的来说,MySQL 8.0官方文档中文版是MySQL数据库的权威参考,对于想要学习和使用MySQL的用户来说,是不可或缺的宝贵资源。 ### 回答2: MySQL官方文档MySQL数据库管理系统的官方技术文档,提供了全面的关于MySQL 8.0版本的信息和指导。 MySQL 8.0官方文档中文版主要包括以下内容: 1. 介绍和安装:文档提供了MySQL 8.0的简介,包括其特性和优势。同时也提供了安装MySQL数据库的详细步骤和注意事项。 2. 数据类型和操作:文档详细介绍了MySQL 8.0支持的各种数据类型,以及这些数据类型的操作和限制。无论是整型、浮点型、日期时间型还是字符串类型,都有详细的解释和示例。 3. 查询语言和操作:文档详细介绍了MySQL 8.0的查询语言(SQL)的语法和用法,包括各种查询语句的编写和执行。同时也介绍了常用的数据操作语句,如插入、更新、删除等。 4. 数据库管理和安全:文档提供了关于MySQL 8.0数据库管理的指南,包括创建和管理数据库、用户和权限的操作。此外,还介绍了如何保护数据库的安全,如使用SSL加密、访问控制等。 5. 性能优化和高可用性:文档提供了关于MySQL 8.0性能优化和高可用性的指导,包括查询优化、索引设计、存储引擎选择等方面的内容。同时也介绍了MySQL复制和集群等高可用性解决方案。 6. 开发接口和工具:文档提供了关于MySQL 8.0的开发接口和工具的介绍和用法,如MySQL Connector、MySQL Workbench等。此外,也提供了一些常用的开发示例和最佳实践。 总之,MySQL 8.0官方文档中文版是MySQL数据库管理系统的权威指南,提供了全面的相关信息和指导。无论是初学者还是有经验的开发者,都可以通过阅读该文档来了解和使用MySQL 8.0。 ### 回答3: MySQL 8.0官方文档已经提供了中文版。它是MySQL数据库的权威参考文档,提供了完整的MySQL 8.0版本的文档信息。中文版官方文档的发布使得中文用户能够更方便地了解和使用MySQL 8.0MySQL 8.0官方文档中文版涵盖了广泛的主题,包括基本概念、安装和升级、配置和管理、备份和恢复、性能优化等。该文档提供了详细的指南和示例,使用户能够更好地理解和使用MySQL 8.0的各种功能和工具。 MySQL 8.0官方文档中的中文翻译准确而清晰,使用简洁明了的语言,使读者能够轻松掌握MySQL 8.0的各个方面。无论是初学者还是有经验的用户,都能够通过这份文档更好地理解和使用MySQL 8.0,从而更高效地管理和操作数据库。 通过阅读MySQL 8.0官方文档的中文版,用户可以学习如何安装和配置MySQL服务器,了解数据库的基本操作和管理,掌握SQL查询语言的基本语法和高级技巧,学习如何进行性能优化和故障排除等。 总而言之,MySQL 8.0官方文档中文版是一份非常有价值的资源,能够帮助中文用户更好地学习和使用MySQL 8.0,实现更高效的数据库管理和开发。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值