热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

目录第八章优化(十三)——块嵌套循环和批量键访问连接8.2优化SQL语句8.2.1优化SELECT语句8.2.1.12块嵌套循环和批量键访问连接块嵌套循

目录

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

    • 8.2 优化SQL语句
      • 8.2.1 优化 SELECT 语句
        • 8.2.1.12 块嵌套循环和批量键访问连接
          • 块嵌套循环和批量键访问算法使用到的连接缓冲区管理
          • 外连接和半连接的块嵌套循环算法
          • 批量键范围连接
          • 块嵌套循环和批量键访问算法的优化器提示


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


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 官方文档 第八章 优化(十四)—— 条件过滤


推荐阅读
  • Explain如何助力SQL语句的优化及其分析方法
    本文介绍了Explain如何助力SQL语句的优化以及分析方法。Explain是一个数据库SQL语句的模拟器,通过对SQL语句的模拟返回一个性能分析表,从而帮助工程师了解程序运行缓慢的原因。文章还介绍了Explain运行方法以及如何分析Explain表格中各个字段的含义。MySQL 5.5开始支持Explain功能,但仅限于select语句,而MySQL 5.7逐渐支持对update、delete和insert语句的模拟和分析。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 本文介绍了使用cacti监控mssql 2005运行资源情况的操作步骤,包括安装必要的工具和驱动,测试mssql的连接,配置监控脚本等。通过php连接mssql来获取SQL 2005性能计算器的值,实现对mssql的监控。详细的操作步骤和代码请参考附件。 ... [详细]
  • MySQL中的MVVC多版本并发控制机制的应用及实现
    本文介绍了MySQL中MVCC的应用及实现机制。MVCC是一种提高并发性能的技术,通过对事务内读取的内存进行处理,避免写操作堵塞读操作的并发问题。与其他数据库系统的MVCC实现机制不尽相同,MySQL的MVCC是在undolog中实现的。通过undolog可以找回数据的历史版本,提供给用户读取或在回滚时覆盖数据页上的数据。MySQL的大多数事务型存储引擎都实现了MVCC,但各自的实现机制有所不同。 ... [详细]
  • 本文介绍了在rhel5.5操作系统下搭建网关+LAMP+postfix+dhcp的步骤和配置方法。通过配置dhcp自动分配ip、实现外网访问公司网站、内网收发邮件、内网上网以及SNAT转换等功能。详细介绍了安装dhcp和配置相关文件的步骤,并提供了相关的命令和配置示例。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 关于我们EMQ是一家全球领先的开源物联网基础设施软件供应商,服务新产业周期的IoT&5G、边缘计算与云计算市场,交付全球领先的开源物联网消息服务器和流处理数据 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • 本文介绍了在MySQL8.0中如何查看性能并解析SQL执行顺序。首先介绍了查询性能工具的开启方法,然后详细解析了SQL执行顺序中的每个步骤,包括from、on、join、where、group by、having、select distinct、union、order by和limit。同时还介绍了虚拟表的概念和生成过程。通过本文的解析,读者可以更好地理解MySQL8.0中的性能查看和SQL执行顺序。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • 本文介绍了Redis中RDB文件和AOF文件的保存和还原机制。RDB文件用于保存和还原Redis服务器所有数据库中的键值对数据,SAVE命令和BGSAVE命令分别用于阻塞服务器和由子进程执行保存操作。同时执行SAVE命令和BGSAVE命令,以及同时执行两个BGSAVE命令都会产生竞争条件。服务器会保存所有用save选项设置的保存条件,当满足任意一个保存条件时,服务器会自动执行BGSAVE命令。此外,还介绍了RDB文件和AOF文件在操作方面的冲突以及同时执行大量磁盘写入操作的不良影响。 ... [详细]
author-avatar
杨浩
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有