mysql中join源码分析,MySQL中Join算法实现原理分析[图]

2023-11-12

在MySQL 中,只有一种 Join 算法,就是大名鼎鼎的 Nested Loop Join,他没有其他很多数据库所提供的 Hash Join,也没有 Sort Merge Join。顾名思义,Nested Loop Join 实际上就是通过驱动表的结果集作为循环基础数据,然后一条一条的通过该结果集中的数据作

在MySQL 中,只有一种 Join 算法,就是大名鼎鼎的 Nested Loop Join,他没有其他很多数据库所提供的 Hash Join,也没有 Sort Merge Join。顾名思义,Nested Loop Join 实际上就是通过驱动表的结果集作为循环基础数据,然后一条一条的通过该结果集中的数据作为过滤条件到下一个表中查询数据,然后合并结果。如果还有第三个参与 Join,则再通过前两个表的 Join 结果集作为循环基础数据,再一次通过循环查询条件到第三个表中查询数据,如此往复。

还是通过示例和图解来说明吧,后面将通过我个人数据库测试环境中的一个 example(自行设计,非MySQL 自己提供) 数据库中的三个表的 Join 查询来执行 示例。

留心:由于这里有些内容须要在MySQL 5.1.18之后的版本中才会体现出来,所以本测试的MySQL 版本为5.1.26

表结构:

1 sky@localhost : example 11:09:32> show create table user_groupG

2

3 *************************** 1. row ***************************

4

5 Table: user_group

6

7 Create Table: CREATE TABLE `user_group` (

8

9 `user_id` int(11) NOT NULL,

10

11 `group_id` int(11) NOT NULL,

12

13 `user_type` int(11) NOT NULL,

14

15 `gmt_create` datetime NOT NULL,

16

17 `gmt_modified` datetime NOT NULL,

18

19 `status` varchar(16) NOT NULL,

20

21 KEY `idx_user_group_uid` (`user_id`)

22

23 ) ENGINE=MyISAM DEFAULT CHARSET=utf8

24

25 1 row in set (0.00 sec)

26

27 sky@localhost : example 11:10:32> show create table group_messageG

28

29 *************************** 1. row ***************************

30

31 Table: group_message

32

33 Create Table: CREATE TABLE `group_message` (

34

35 `id` int(11) NOT NULL AUTO_INCREMENT,

36

37 `gmt_create` datetime NOT NULL,

38

39 `gmt_modified` datetime NOT NULL,

40

41 `group_id` int(11) NOT NULL,

42

43 `user_id` int(11) NOT NULL,

44

45 `author` varchar(32) NOT NULL,

46

47 `subject` varchar(128) NOT NULL,

48

49 PRIMARY KEY (`id`),

50

51 KEY `idx_group_message_author_subject` (`author`,`subject`(16)),

52

53 KEY `idx_group_message_author` (`author`),

54

55 KEY `idx_group_message_gid_uid` (`group_id`,`user_id`)

56

57 ) ENGINE=MyISAM AUTO_INCREMENT=97 DEFAULT CHARSET=utf8

58

59 1 row in set (0.00 sec)

60

61 sky@localhost : example 11:10:43> show create table group_message_contentG

62

63 *************************** 1. row ***************************

64

65 Table: group_message_content

66

67 Create Table: CREATE TABLE `group_message_content` (

68

69 `group_msg_id` int(11) NOT NULL,

70

71 `content` text NOT NULL,

72

73 KEY `group_message_content_msg_id` (`group_msg_id`)

74

75 ) ENGINE=MyISAM DEFAULT CHARSET=utf8

76

77 1 row in set (0.00 sec)

运用 Query如下:

1 select m.subject msg_subject, ntent msg_content

2

3 from user_group g,group_message m,group_message_content c

4

5 where g.user_id = 1

6

7 and m.group_id = g.group_id

8

9 and c.group_msg_id = m.id

看看我们的 Query 的执行计划:

1 sky@localhost : example 11:17:04> exp lain select m.subject msg_subject, ntent msg_content

2

3 -> from user_group g,group_message m,group_message_content c

4

5 -> where g.user_id = 1

6

7 -> and m.group_id = g.group_id

8

9 -> and c.group_msg_id = m.idG

10

11 *************************** 1. row ***************************

12

13 id: 1

14

15 select_type: SIMPLE

16

17 table: g

18

19 type: ref

20

21 possible_keys: user_group_gid_ind,user_group_uid_ind,user_group_gid_uid_ind

22

23 key: user_group_uid_ind

24

25 key_len: 4

26

27 ref: const

28

29 rows: 2

30

31 Extra:

32

33 *************************** 2. row ***************************

34

35 id: 1

36

37 select_type: SIMPLE

38

39 table: m

40

41 type: ref

42

43 possible_keys: PRIMARY,idx_group_message_gid_uid

44

45 key: idx_group_message_gid_uid

46

47 key_len: 4

48

49 ref: example.g.group_id

50

51 rows: 3

52

53 Extra:

54

55 *************************** 3. row ***************************

56

57 id: 1

58

59 select_type: SIMPLE

60

61 table: c

62

63 type: ref

64

65 possible_keys: idx_group_message_content_msg_id

66

67 key: idx_group_message_content_msg_id

68

69 key_len: 4

70

71 ref: example.m.id

72

73 rows: 2

74

75 Extra:

我们可以看出,MySQL Query Optimizer 选择了 user_group 作为驱动表,首先运用 我们传入的条件 user_id 通过 该表上面的索引 user_group_uid_ind 来执行 const 条件的索引 ref 查找,然后以 user_group 表中过滤出来的结果集的 group_id 字段作为查询条件,对 group_message 循环查询,然后再通过 user_group 和 group_message 两个表的结果集中的 group_message 的 id 作为条件 与 group_message_content 的 group_msg_id 比较执行 循环查询,才得到最终的结果。没啥特别的,后一个引用前一个的结果集作为条件,实现流程可以通过下图表示:

下面的我们调整一下 group_message_content 去掉上面的 idx_group_message_content_msg_id 这个索引,然后再看看会是什么效果:

1 sky@localhost : example 11:25:36> drop index idx_group_message_content_msg_id on group_message_content;

2

3 Query OK, 96 rows affected (0.11 sec)

4

5 sky@localhost : example 10:21:06> exp lain

6

7 -> select m.subject msg_subject, ntent msg_content

8

9 -> from user_group g,group_message m,group_message_content c

10

11 -> where g.user_id = 1

12

13 -> and m.group_id = g.group_id

14

15 -> and c.group_msg_id = m.idG

16

17 *************************** 1. row ***************************

18

19 id: 1

20

21 select_type: SIMPLE

22

23 table: g

24

25 type: ref

26

27 possible_keys: idx_user_group_uid

28

29 key: idx_user_group_uid

30

31 key_len: 4

32

33 ref: const

34

35 rows: 2

36

37 Extra:

38

39 *************************** 2. row ***************************

40

41 id: 1

42

43 select_type: SIMPLE

44

45 table: m

46

47 type: ref

48

49 possible_keys: PRIMARY,idx_group_message_gid_uid

50

51 key: idx_group_message_gid_uid

52

53 key_len: 4

54

55 ref: example.g.group_id

56

57 rows: 3

58

59 Extra:

60

61 *************************** 3. row ***************************

62

63 id: 1

64

65 select_type: SIMPLE

66

67 table: c

68

69 type: ALL

70

71 possible_keys: NULL

72

73 key: NULL

74

75 key_len: NULL

76

77 ref: NULL

78

79 rows: 96

80

81 Extra: Using where; Using join buffer

我们看到不仅仅 group_message_content 表的访问从 ref 变成了 ALL,此外,在最后一行的 Extra信息从没有任何内容变成为 Using where; Using join buffer,也就是说,对于从 ref 变成 ALL 很容易理解,没有可以运用的索引的索引了嘛,当然得执行 全表扫描了,Using where 也是因为变成全表扫描之后,我们须要取得的 content 字段只能通过对表中的数据执行 where 过滤才能取得,但是后面出现的 Using join buffer 是一个啥呢?

我们知道,MySQL 中有一个供我们配置的参数 join_buffer_size ,这里实际上就是运用到了通过该参数所配置的 Buffer 区域。那为啥之前的执行计划中没有用到呢?

实际上,Join Buffer 只有当我们的 Join 类型为 ALL(如示例中),index,rang 或者是 index_merge 的时候 才能够运用,所以,在我们去掉 group_message_content 表的 group_msg_id 字段的索引之前,由于 Join 是 ref 类型的,所以我们的执行计划中并没有看到有运用 Join Buffer。

当我们运用了 Join Buffer 之后,我们可以通过下面的这张图片来表示 Join 完成流程:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

mysql中join源码分析,MySQL中Join算法实现原理分析[图] 的相关文章

  • 游戏的基础—三消-1

    三消 简单的理解就是3个在一起就消喽 这里我们就最简单的操作的三消为例 就是你触屏按下去 然后以当前的位置像周围4个方向寻找是否有相同类型的游戏实体 如果有的话 把它存进一个list的里面 这里要强调一下c 里面数组一般用list因为lis
  • 字节(飞书)暑期实习面试记录

    字节一面 2022 05 07 20 00 21 20 前导 面试官简单介绍字节和面试注意点 1 自我介绍 问实习能多久 2 项目介绍部分 问 实习了多久 介绍项目 项目收获 项目难点 怎样轮询日志的 因为我项目介绍时候有提到 3 正片开始
  • 软考-信息管理——学习笔记_证

    前言 学习方法 应该达到 按照一级标题进行默写罗列 再默写二级标题默写罗列 最后按三级标题及知识点进行罗列 合同和法律篇 中标通知书发送30天内需签订合同 标底保密 招标文件发布起到截止日不得少于20天 不用招标的场景 需要采用不可代替的专
  • Eolink 旗下网关产品各版本功能及性能对比

    GoKu 网关提供企业版 EE 与开源版 CE 两个版本 满足不同阶段用户对于微服务的需求 两个版本均支持 私有云部署 开源版 CE 目前已停止维护 Apinto 开源版本是 Goku 开源版 CE 的一次架构升级 经过前面几年的网关架构和
  • 图像识别技术

    目录 1 什么是图像识别 2 图像识别的发展过程 3 图像识别的原理 4 图像识别的应用领域 5 图像识别未来的发展趋势 1 什么是图像识别 图像识别 又称为计算机视觉 是指利用计算机和人工智能技术对图像进行分析和理解 以自动识别和分类图像
  • Java并发之锁

    Java并发之锁 一 临界区 二 线程安全 三 解决临界区线程安全问题 四 Java对象头 五 重量级锁 Monitor 5 1 synchronized 5 1 1 synchronized加锁流程 六 轻量级锁 6 1 轻量级锁加锁流程
  • 信息收集的一些文件泄露

    1 robots txt文件泄露 放在网站的跟目录下 用于限制浏览器的访问 哪些可以抓取 哪些不能抓取 用于防止黑客 但是任何人可在url中直接通过 robots txt访问 导致网站结构被泄露 可对admin等重要文件设置密保保护 或者采
  • 【Python打包成exe方法】——已解决导入第三方包无法打包的问题​

    前言 在我们写代码的过程中 我们开发的脚本一般都会用到一些第三方包 可能别人也需要用到我们的脚本 如果我们将我们的xx py文件发给他 他是不能直接用的 他还需要安装python解释器 甚至还要安装我们用的那些第三方包 是不是有点小麻烦 但
  • Openmmlab(一)

    计算机视觉为研究如何自动理解图像和视频中的内容 运用于图像识别 人脸识别 计算机视觉应用 动漫特效 图像生成 风格迁移 虚拟主播 视频自动剪辑等 今日的计算机视觉 文字描述生成图片 视觉大模型 神经渲染CityNeRF 开源成为人工智能领域
  • js逆向webpack

    扣代码会遇到的基本2种形式 1 webpack function x 这里的x是存放模块1 模块2那个数组 function xx yy yy是存放模块1 模块2的数组下标 x yy call 模块参数1 模块参数2 模块参数3 必有一个加
  • 双系统ubuntu20.04(neotic版本)从0实现Gazebo仿真slam建图

    双系统ubuntu20 04 neotic版本 从0实现Gazebo仿真slam建图 昨晚完成了ROS的多机通讯 还没来得及整理相关操作步骤 在进行实际小车的实验之前 还是先打算在仿真环境中进行测试 熟悉相关的操作步骤 计划通过虚拟机 笔记
  • 【实验分享】CCIE—BGP反射器实验

    实验目的 l掌握BGP反射器的运行原理 l理解反射器的用途以及好处 实验说明 l通过此实验练习 可以灵活的使用BGP反射器 实验环境 l三台支持SPSERVICES的IOS的路由器 l直通线 实验拓扑 实验步骤 R1 config inte
  • alibaba fastjson jsonarray转list

    String avatar teacherEntity getAvatar if StringUtils isEmpty avatar List
  • Python——元类

    作者 小明 链接 https zhuanlan zhihu com p 30861351 来源 知乎 著作权归作者所有 商业转载请联系作者获得授权 非商业转载请注明出处 什么是元类 理解元类 metaclass 之前 我们先了解下Pytho
  • 阿里云轻量级服务器部署网站 安装java+tomcat+Mysql

    网上关于部署服务器的教程已经是数不胜数 按理来说不应该重复造轮子 但是网上的教程没有很好的整合文章 于是乎笔者本着写一篇整合性 参考性比较强的角度出发写了这篇文章 本文详细写了阿里云轻量级服务器的安装jdk tomcat mysql部署简单
  • Window 10 系统 在命令行中输入python会跳转到商店问题解决

    在Windows 10 中配置了python的环境变量 但是在命令行中输入python会跳转到商店 这是由于在环境变量中path配置了 USERPROFILE AppData Local Microsoft WindowsApps 导致 只
  • 东北大学acm训练第五周

    include
  • mysql using filesort

    今天在explain一个MySQL的sql语句的时候 产生了 如下的结果 extra那一栏多了一个Using filesort 而却type也是ALL这说明了查询的结果是全表扫描 可是笔者明明就在 public time字段加了索引 然而笔
  • 只通过com.alibaba.fastjson.JSONArray实现okHttp下String转换JSONArray

    我的Android不能导入常见的那六个包 会严重报错 我改了很久很久还是不能解决错误 也就不能使用net sf包中的JSONArray 直接使用new JSONArray str 给像我一样不能导入包的同学介绍一种方法 import com

随机推荐

  • 浅谈 js reduce()

    reduce 为数组中的每一个元素依次 执行回调函数 不包括数组中被删除的元素或者未赋值的元素 接受四个参数 初始值 或者上次回调函数的返回值 当前元素值 当前索引 调用reduce的数组 语法 arr reduce function pr
  • 在电脑上安装虚拟机

    百度搜索一下 VMware Workstation 下载安装完成之后 找个破解码破解了即可 然后就下载对应的操作系统的iso文件 加载到虚拟机中即可
  • 进制数字的输入和输出

    写个程序 它读取一个整数并以二进制 八进制 和十六进制输出 以十六进制浮点数输出倒数 public class test1 public static void main String args 写个程序 它读取一个整数并以二进制 八进制
  • 免费公开课

    https www edx org course
  • 【Visual Studio】调试过程中VS卡死无响应

    最近在使用vs2022 debug调试过程中 经常出现vs2022直接卡死无响应 解决方案 第一种原因 是加载符号导致 调试 选项 符号 1 取消勾选 xxx 符号服务器 2 选择 仅加载指定的模块 第二种情况 VS卡死后 把崩溃dmp导出
  • 实时操作系统-与QNX比较-qnx系统优势-qnx性能分析-qnx系统性能分析

    锋影 e mail 174176320 qq com LynxOS QNX Linux的分析和比较 本文对四种实时操作系统 RTOS 特性进行分析和比较 它们是 Lynx实时系统公司的LynxOS QNX软件系统有限公司的QNX以及两种具有
  • 解决爬虫登陆电信密码加密问题

    遇见问题 写爬虫抓取电信数据 在登陆时发现密码加密问题 扒出加密函数如下 fn aesEncrypt function n var t CryptoJS MD5 login 189 cn i CryptoJS enc Utf8 parse
  • 使用kettle转换中的JavaScript对密码进行加密和解密

    日常开发中 为了确保账号和密码的安全 时常要对密码进行加密和解密 然而kettle是怎么对密码进行加密和解密的呢 下面的代码需要再转换中的JavaScript中运行 var encrypted password not encrypted
  • JDBC操作postgresql(javaweb)

    首先 postgresql的几个常见 语句结尾一定要加分号 语句结尾一定要加分号 语句结尾一定要加分号 如果是变量不要加引号 sql语句要加引号 1 常见命令 先进入安装的bin目录下 psql exe U postgres 连接数据库 h
  • linux:cloudflare证书申请及应用到nginx

    参考 免费申请网站SSL证书 有效期15年 全站开启https 哔哩哔哩 bilibili 总结 登陆www cloudflare com 注册账号 Add a Site 增加站点 站点设置完毕后Add record 记住这个Proxy s
  • JAVA之单元测试:Junit框架

    单元测试 单元测试就是针对最小的功能单元编写测试代码 Java程序最小的功能单元是方法 因此 单元测试就是针对Java方法的测试 进而检查方法的正确性 目前测试方法是怎么进行的 存在什么问题 1 只有一个main方法 如果一个方法的测试失败
  • BIP上传模版报错 SBL-EAI-04308

    问题 BIP里面上传模版时报如下错误 Siebel 1 0 Web 服务 的操作 SBL EAI 04308 IDS EAI WS OD FAULT 2 对象管理器错误 0 Web 服务 的操作 SBL EAI 04308 IDS EAI
  • win10双屏锁屏后再登陆导致副屏窗口全部移到主屏的解决方法

    win10双屏锁屏后再登陆导致副屏窗口全部移到主屏的解决方法 其实是锁屏后屏幕关闭了 在重新打开时 会将所有窗口移动到主屏幕 解决方法 修改锁屏后屏幕关闭时间 具体请看http www xitongcheng com jiaocheng w
  • 字符串哈希

    字符串哈希 我们可以把一个字符串哈希处理成一个数字 具体做法 将字符串看作是一个p进制数 p大于字符的ascii码值 acbd哈希成数字是 a p 3 c p 2 b p 1 d p 0 modQ p一般取131或者13331 Q取2e64
  • Docker学习笔记

    五 Docker 1 简介 Docker是一个开源的应用容器引擎 是一个轻量级容器技术 Docker支持将软件编译成一个镜像 然后在镜像中各种软件做好配置 将镜像发布出去 其他使用者可以直接使用这个镜像 运行中的这个镜像称为容器 容器启动是
  • 微信小程序静态初步

    社团微信小程序 1 由于兴趣驱动 一直在学习微信小程序 由于之前一直学习Java 但是大三第一学期即将结尾 所以为了能让下学期的学习减少工作量所以就打算利用闲散时间开发小程序 于是就拿社团为例子 自己一步步摸索 现在只是初步学习 所以这些天
  • mysql-Innodb事务隔离级别-repeatable read详解(转)

    mysql Innodb事务隔离级别 repeatable read详解 转 一 事务隔离级别 ANSI ISO SQL标准定义了4中事务隔离级别 未提交读 read uncommitted 提交读 read committed 重复读 r
  • vim配置经典

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 在终端 输入以下命令来编辑vimrc配置文件 sudo vim etc vim vimrc 或者 sudo gedit etc vim vimrc 将其复制粘贴进去 Des
  • GeoDa:入门基础

    前言 GeoDa是一个免费的开源软件工具 用于空间数据分析 它旨在通过探索和建模空间模式来促进数据分析的新见解 GeoDa是由Luc Anselin博士和他的团队开发的 该项目为探索性空间数据分析 ESDA 方法提供了用户友好的图形界面 例
  • mysql中join源码分析,MySQL中Join算法实现原理分析[图]

    在MySQL 中 只有一种 Join 算法 就是大名鼎鼎的 Nested Loop Join 他没有其他很多数据库所提供的 Hash Join 也没有 Sort Merge Join 顾名思义 Nested Loop Join 实际上就是通