iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >技术分享 | Hash join in MySQL 8
  • 814
分享到

技术分享 | Hash join in MySQL 8

技术分享|HashjoininMySQL8 2020-01-17 08:01:01 814人浏览 绘本
摘要

作者:Erik Frøseth 翻译:管长龙 原文:https://Mysqlserverteam.com/hash-join-in-mysql-8/ 长期以来,在 Mysql 中执行 join 查询的只是嵌套循环算法的变体。随着 My

作者:Erik Frøseth 翻译:管长龙 原文:https://Mysqlserverteam.com/hash-join-in-mysql-8/

长期以来,在 Mysql 中执行 join 查询的只是嵌套循环算法的变体。随着 MySQL 8.0.18 的发布,现在可以使用 Hash join 执行 joins。这篇博客文章将介绍它的工作原理,使用时间以及在性能方面与 MySQL 中旧的 join 算法的比较。

什么是 Hash join?

Hash join 是一种执行 join 的方式,其中哈希表用于查找两个输入之间的匹配行(一个输入是一个或多个表)。它通常比嵌套循环 join 更有效,特别是如果其中一个输入可以容纳在内存中时。为了查看其工作方式,我们将使用以下查询作为示例:

SELECT
  given_name, country_name
FROM
  persons JOIN countries ON persons.country_id = countries.country_id;

① 构建阶段

通常 Hash join 分为两个阶段:构建阶段和探测阶段。

在构建阶段,服务使用联接属性作为哈希表键,构建一个内存中的哈希表,其中存储来自输入之一的行。此输入也称为构建输入,让我们假设将 countries 指定为构建输入。理想情况下,服务将选择两个输入中较小的一个作为构建输入(以字节为单位,而不是行数)。

由于 countries.country_id 是属于构建输入的联接条件,因此将其用作哈希表中的键。一旦所有行都存储在哈希表中,就完成了构建阶段。

② 探测阶段

在探测阶段,服务开始从探测输入(在我们的示例中为 persons )读取行。 对于每一行,服务都会使用 persons.country_id 中的值作为查找键来探测哈希表是否匹配行。对于每个匹配项,将向客户端发送一个合并的行。最后,服务仅扫描每个输入一次,使用恒定时间查找来查找两个输入之间的匹配行。

假设服务可以将整个构建输入存储在内存中,则此方法非常有效。可用的内存量由系统变量 join_buffer_size 控制,可以在运行时进行调整。但是,如果构建输入大于可用内存,会发生什么?我们溢出到磁盘上!

③ 溢出到磁盘

在构建阶段内存已满时,服务器会将其余的构建输入写出到磁盘上的多个块文件中。服务器试图设置块的数量,以使最大的块恰好适合内存(我们很快就会知道为什么),但每次输入的块文件个数严格上限是 128。通过计算 join 属性的哈希值来确定将行写入哪个块文件。请注意,在图示中,使用了与内存构建阶段中使用的哈希函数不同的哈希函数。稍后我们将了解原因。

在探测阶段,服务器会探测哈希表中的匹配行,就像所有内容都适合内存一样。但是除此之外,一行还可能与写入磁盘的构建输入中的一行匹配。因此,来自探测输入的每一行也被写入一组块文件。使用将构建输入写入磁盘时使用的哈希函数和公式确定将行写入哪个块文件。这样,我们可以确定两个输入之间的匹配行将位于同一对块文件中。

探测阶段完成后,我们开始从磁盘读取块文件。通常,服务器使用第一组块文件作为构建和探测输入来执行构建和探测阶段。我们将构建输入中的第一个块文件加载到内存中的哈希表中。这解释了为什么我们希望最大的块恰好适合内存。如果块文件太大,我们需要将其分成更小的块。加载构建块后,我们从探测输入读取相应的块文件,并在哈希表中探测匹配项,就像所有内容都适合内存一样。处理完第一对块文件后,我们将移至下一对块文件,继续进行直到所有对块文件都已处理为止。

您现在可能已经猜到了为什么在将行划分为块文件并将行写入哈希表时,为什么应该使用两个不同的哈希函数。如果我们要对两个操作使用相同的哈希函数,则在将构建块文件加载到哈希表中时,将得到一个非常糟糕的哈希表,因为同一块文件中的所有行都将哈希成相同的值。

这么赞,我该如何使用?

Hash join 默认情况下处于启用状态,因此无需执行任何操作即可使用哈希联接。值得注意的是,Hash join 建立在新的迭代器执行器上,这意味着您必须使用 EXPLaiN FORMAT = tree 来查看是否将使用 Hash join:

mysql> EXPLAIN FORMAT=tree
    -> SELECT
    ->   given_name, country_name
    -> FROM
    ->   persons JOIN countries ON persons.country_id = countries.country_id;
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| EXPLAIN                                                                                                                                                                                                 |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| -> Inner hash join (countries.country_id = persons.country_id)  (cost=0.70 rows=1)
    -> Table scan on countries  (cost=0.35 rows=1)
    -> Hash
        -> Table scan on persons  (cost=0.35 rows=1)     |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

通常,如果使用一个或多个等联接条件将表联接在一起,并且联接条件没有索引,则将使用 Hash join。如果索引可用,则 MySQL 倾向于使用带有索引查找的嵌套循环。

我们引入了一个新的优化器开关,使您可以对任何查询禁用 Hash join:

mysql> SET optimizer_switch="hash_join=off";
Query OK, 0 rows affected (0.00 sec)

mysql> EXPLAIN FORMAT=tree
    -> SELECT
    ->   given_name, country_name
    -> FROM
    ->   persons JOIN countries ON persons.country_id = countries.country_id;
+----------------------------------------+
| EXPLAIN                                |
+----------------------------------------+
|										 |
+----------------------------------------+
1 row in set (0.00 sec)

禁用 Hash join 后,MySQL 将退回到块嵌套循环,从而使用旧的执行程序(迭代器执行程序不支持块嵌套循环)。此开关使比较 Hash join 和块嵌套循环的性能变得容易。

如果由于构建输入太大而导致无法容纳在内存中并使用磁盘,则可以增加连接缓冲区的大小。与块嵌套循环相反,Hash join 将递增地分配内存,这意味着它将永远不会使用超出其需求的内存。因此,使用 Hash join 连接时,使用较大的连接缓冲区大小更安全

性能数据!

我们做了一些基准测试以查看 Hash join 与块嵌套循环相比如何,结果看起来像这样:

您可以在此处查看结果的演示。首先,我必须提到在此测试中我们确实禁用了所有索引。这是为了使优化器使用块嵌套循环和 Hash join 来创建执行计划,因此您在此处看到的数字不会显示出对 DBT-3 执行时间的总体改进。进行此测试是为了突出块嵌套循环和 Hash join 之间的区别。但是我们可以看到,在所有使用 Hash join 的查询中,Hash join 显然都优于块嵌套循环。调整了缓冲池的大小,以便所有数据都在内存中,并且连接缓冲区的大小与默认值(约 250kB)保持不变。显着的改进是由于以下事实:每次输入 Hash join 仅扫描一次,并且它使用恒定时间查找来查找两个表之间的匹配行。

遗憾的是,当前 Hash join 的实现存在一些限制:

MySQL 仅支持内部 Hash join,这意味着反,半和外部联接仍使用块嵌套循环执行。 优化器/计划器使用块嵌套循环执行连接。但应该更频繁地使用 Hash join。 我们希望将来消除这两个限制,但是即使存在这两个限制,哈希联接也应使您的查询运行更快。

您可能感兴趣的文档:

--结束END--

本文标题: 技术分享 | Hash join in MySQL 8

本文链接: https://www.lsjlt.com/news/2424.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 分享8个令人震惊的HTML技巧
    本篇文章给大家带来了关于HTML 的相关知识,其中主要跟大家分享8个HTML 技巧,感兴趣的朋友下面一起来看一下吧,希望对大家有帮助。1. 捕获属性打开你的设备摄像头正如 input 标记具有 email、 text 和 password ...
    99+
    2023-05-14
    html 前端
  • 用AJAX技术聚合RSS284475分享
    有时候,你的Blog可能需要这样的功能:  在自己Blog上聚合并显示朋友Blog的最新文章,这样方便自己及时了解朋友的消息,另外,也方便访问者找到和本Blog相关的blo...
    99+
    2023-05-20
    用AJAX技术聚合RSS
  • 【整理分享】8 个实用Vue开发技巧
    本篇文章整理分享8 个很棒的 Vue 开发技巧,包括路由参数解耦、功能组件、样式范围、watch的高级使用、watch监听多个变量等,希望对大家有所帮助!1.路由参数解耦通常在组件中使用路由参数,大多数人会做以下事情。export defa...
    99+
    2023-05-14
    Vue
  • 8个JavaScript条件语句优化小技巧分享
    目录1、Array.includes2、Array.every3、尽早 return4、三元运算符5、switch...case6、Map/Object7、默认函数参数和解构8、逻辑...
    99+
    2024-04-02
  • 常见的反爬虫urllib技术分享
    目录通过robots.txt来限制爬虫:通过User-Agent来控制访问:验证码:IP限制:cookie:JS渲染:爬虫和反爬的对抗一直在进行着…为了帮助更好的进行爬...
    99+
    2024-04-02
  • Android WebRTC 对 AudioRecord 的使用技术分享
    目录一、创建和初始化二、启动三、读数据四、停止和销毁前言: AudioRecord 是 Android 基于原始PCM音频数据录制的类,WebRCT 对其封装的代码位置位于org/w...
    99+
    2024-04-02
  • Java多线程与线程池技术分享
    目录一、序言1、普通执行2、线程池执行二、线程池基础1、核心参数2、参数与池的关系1、通用对比2、拓展对比3、无返回值任务4、有返回值任务三、Executors1、创建单一线程的线程...
    99+
    2024-04-02
  • Golang替换空格的实用技术分享
    标题:Golang替换空格的实用技术分享 随着互联网的普及和发展,程序设计和开发变得愈发重要。在编程过程中,数据处理是一个非常关键的部分。处理文本数据时,常常会遇到需要替换空格的情况,...
    99+
    2024-03-13
    golang 替换 空格 golang开发
  • 技术分享:KVM虚拟化如何取证?
    虚拟化技术应用越来越广泛,在国内虚拟化市场,按销售额已经五年成两位数增长了。对于我们取证业行来说也迫切需要了解一些虚拟化相关的知识,今天美亚技术专家为大家带来使用Linux KVM虚拟化技术的取证研究。什么是KVM?KVM是Kernel-b...
    99+
    2023-06-04
  • Mysql相关技术举例分析
    本篇内容介绍了“Mysql相关技术举例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1.复制过滤问题:...
    99+
    2024-04-02
  • GO语言开发技术:学习笔记分享!
    GO语言是一门高效、可靠、可扩展的编程语言,由Google开发。它的出现解决了许多其他编程语言的问题,例如C++中的指针问题、Java中的垃圾回收等等。 GO语言在现代化的软件开发中,已经被广泛应用,并成为了云计算领域的事实标准。本篇文章...
    99+
    2023-08-02
    学习笔记 开发技术 linux
  • PHP并发编程技术实践:Git开发技巧分享
    PHP并发编程技术实践:Git开发技巧分享 随着互联网技术的快速发展,Web应用程序的规模越来越大,对服务器的负载能力要求也越来越高。如何在高并发的情况下保证Web应用程序的稳定性,是每个Web开发人员都需要面对的问题。在PHP开发中,使用...
    99+
    2023-06-03
    并发 git 开发技术
  • Java 对象开发技术中函数编写技巧分享
    Java 是一种面向对象的编程语言,对象是 Java 程序的基本单元。在 Java 对象开发中,函数是对象的基本行为,是实现对象功能的关键。因此,函数编写技巧对于 Java 对象开发非常重要。在本文中,我们将分享几个 Java 对象开发中...
    99+
    2023-07-05
    对象 开发技术 函数
  • 分享MySQL中锁的使用技巧
    MySQL 锁的使用技巧分享随着数据库应用的日益广泛,对数据库的并发控制和数据完整性要求也越来越高。在MySQL数据库中,锁是一种重要的并发控制手段,可以有效地保护数据的完整性和一致性。本文将对MySQL锁的使用技巧进行详细分享,并提供具体...
    99+
    2023-12-21
    MySQL 技巧
  • PHP技术分享:优化QQ空间页面设计
    在互联网时代,网页设计变得越来越重要,一个好的页面设计可以吸引用户,提高用户体验,增加页面访问量。在开发网页的过程中,如何优化页面设计,提高页面加载速度成为了开发者们关注的焦点。本文将...
    99+
    2024-03-15
    优化 php 页面设计 异步加载
  • 知名技术作家分享Python零基础教程!
    最近这段时间,身边常常有人问:该不该学Python?如何学Python? Python包含的内容很多,加上各种标准库、拓展库,乱花渐欲迷人眼。 很多初学者都迫切希望能出现一个容易上手、言语简洁的Python教程,最好是能循序渐进,...
    99+
    2023-01-31
    基础教程 知名 作家
  • 技术分享|ueditor漏洞利用&源码分析超详细分析
    UEditor是一款基于web技术的所见即所得富文本编辑器,广泛应用于各种web应用中。但是,近年来,由于其漏洞导致的安全问题也受到了广泛关注。本文将详细介绍ueditor的漏洞利用及其C#版本的源码解析。 1.漏洞简介 ueditor的漏...
    99+
    2023-09-27
    服务器 安全 网络
  • 好程序员技术分享html5和JavaScript的区别
    好程序员技术分享html5和JavaScript的区别,HTML5广义上讲是前端开发学科的代名词,包含HTML5、CSS3及JavaScript三个重要的部分,是运行在浏览器上应用的统称。如PC端网站、管理系统、手机网页应用(WebApps...
    99+
    2023-06-03
  • mysql表分区技术详细介绍
    1、概述     数据库单表到达一定量后,性能会有衰减,像mysql\sql server等犹为明显,所以需要把这些数据进行分区处理。同时有时候可能出现数据剥离什么的,分区...
    99+
    2024-04-02
  • 经典技术书籍分享(6):WCF服务编程
    这本经典的WCF书籍,第三版,针对.NET4.0做的修改更新。已经于2010年10月份出版了。目前概述英文版已经可以在Amazon购买。网上也出现了电子版的下载。Oreilly.Programming.WCF.Services.3rd.Ed...
    99+
    2023-01-31
    书籍 经典 技术
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作