MySQL Join连接算法深入解析

news2025/5/15 20:52:53

引言

在关系型数据库中,Join操作是实现多表数据关联查询的关键手段,直接影响查询性能和资源消耗。MySQL支持多种Join算法,包括经典的索引嵌套循环连接(Index Nested-Loop Join)、块嵌套循环连接(Block Nested-Loop Join)以及针对大数据量场景优化的批量键访问(Batched Key Access,BKA)和多范围读取(Multi-Range Read,MRR)等先进技术。本文将系统介绍这些Join算法的原理、工作流程及其适用场景,重点解析BKA和MRR如何通过批量化访问和顺序读取优化I/O性能。同时,结合实际案例讲解如何通过临时表和索引优化Join执行过程,最后简要比较MySQL未支持的排序归并连接(Sort-Merge Join)算法,帮助读者全面掌握MySQL多表关联查询的优化策略与实践。

Index Nested-Loop Join(NLJ)

select * from t1 straight_join t2 on (t1.a=t2.a);

  • 从表 t1 中读入一行数据 R;
  • 从数据行 R 中,取出 a 字段到表 t2 里去查找;
  • 取出表 t2 中满足条件的行,跟 R 组成一行,作为结果集的一部分;
  • 重复执行步骤 1 到 3,直到表 t1 的末尾循环结束;

Block Nested-Loop Join(BNL)

select * from t1 straight_join t2 on (t1.a=t2.b);

BNL使用join buffer存储左表数据,左表数据太多会分段与右表进行关联。

  • 把表 t1 的数据读入内存 join_buffer 中,由于我们这个语句中写的是 select *,因此是把整个表 t1 放入了内存。
  • 扫描表 t2,把表 t2 中的每一行取出来,跟 join_buffer 中的数据做对比,满足 join 条件的,作为结果集的一部分返回。

Batched Key Access(BKA)

MySQL 在 5.6 版本后开始引入的 Batched Key Access(BKA)算法,BKA 算法就是对 NLJ 算法的优化

Multi-Range Read(MRR)

MRR 优化的主要目的是尽量使用顺序读盘。

select * from t1 where a>=1 and a<=100;

未使用 MRR 查询思路

主键索引是一棵 B+ 树,在这棵树上,每次只能根据一个主键 id 查到一行数据。因此,回表肯定是一行行搜索主键索引的。

MRR 优化的设计思路:

  • 根据索引 a,定位到满足条件的记录,将 id 值放入 read_rnd_buffer 中 ;
  • 将 read_rnd_buffer 中的 id 进行递增排序;
  • 排序后的 id 数组,依次到主键 id 索引中查记录,并作为结果返回;

将原先的随机回表变成了顺序回表,可以提高回表效率。

如何开启 BKA

如果要使用 BKA 优化算法的话,需要开启相应配置,两个参数的作用是要启用 MRR。

set optimizer_switch='mrr=on,mrr_cost_based=off,batched_key_access=on';

BKA 工作原理

  • 将外部表(左表)中相关的列放入Join Buffer中。
  • 内部表(右表)批量的将Join Buffer中的索引列(索引键值)发送到Multi-Range Read(MRR)接口。
  • Multi-Range Read(MRR)通过收到的Key,根据其对应的ROWID进行排序,然后再进行数据的读取操作。
  • 将读取到的数据和左表的数据组合,得到结果集,最后将结果集返回给客户端。

BNL 转 BKA

select * from t1 join t2 on (t1.b=t2.b) where t2.b>=1 and t2.b<=2000;

如果使用 BNL 算法来 join 的话,这个语句的执行流程是这样的:

  • 把表 t1 的所有字段取出来,存入 join_buffer 中。这个表只有 1000 行,join_buffer_size 默认值是 256k,可以完全存入。
  • 扫描表 t2,取出每一行数据跟 join_buffer 中的数据进行对比。
    • 如果不满足 t1.b=t2.b,则跳过。
    • 如果满足 t1.b=t2.b, 再判断其他条件,也就是是否满足 t2.b 处于[1,2000]的条件,如果是,就作为结果集的一部分返回,否则跳过。

临时表 + BKA优化后的执行流程:

  • 把表 t2 中满足条件的数据放在临时表 tmp_t 中;
  • 为了让 join 使用 BKA 算法,给临时表 tmp_t 的字段 b 加上索引;
  • 让表 t1 和 tmp_t 做 join 操作;
create temporary table temp_t(id int primary key, a int, b int, index(b))engine=innodb;
insert into temp_t select * from t2 where b>=1 and b<=2000;
select * from t1 join temp_t on (t1.b=temp_t.b);

Sort-Merge Join(SMJ)

Sort-Merge Join(SMJ)就是排序归并连接算法,也被称为Merge Join,MySQL不支持这种连接算法。SMJ可以分为排序和归并两个阶段:

  • 第一阶段是排序,就是对Outer表和Inner表进行排序,排序的依据就是每条记录在连接键上的数值。
  • 第二阶段就是归并,因为两张表已经按照同样的顺序排列,所以Outer表和Inner表各一次循环遍历就能完成比对工作了。

归并过程

  • 比较 Outer[i] 和 Inner[j] 的连接键。
  • 如果 Outer[i].id<Inner[j].id,则增加 i 的值。
  • 如果 Outer[i].id>Inner[j].id,则增加 j 的值。
  • 如果 Outer[i].id=Inner[j].id,说明找到了匹配的记录,将其输出到结果集,并分别增加 i 和 j 的值。

选择哪个表作为驱动表

决定哪个表做驱动表的时候,应该是两个表按照各自的条件过滤,过滤完成之后,计算参与 join 的各个字段的总数据量,数据量小的那个表,就是“小表”,应该作为驱动表。


感谢您的阅读!如果文章中有任何问题或不足之处,欢迎及时指出,您的反馈将帮助我不断改进与完善。期待与您共同探讨技术,共同进步!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2376356.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

http请求卡顿

接口有时出现卡顿&#xff0c;而且抓包显示有时tcp目标机器没有响应&#xff0c; 但nginx和java应用又没有错误日志&#xff0c;让人抓耳挠腮&#xff0c;最终还是请运维大哥帮忙&#xff0c;一顿操作后系统暂时无卡顿了&#xff0c;佩服的同时感觉疑惑到底调整了啥东…

vite+vue建立前端工程

​ 参考 开始 | Vite 官方中文文档 VUE教程地址 https://cn.vuejs.org/tutorial/#step-1 第一个工程 https://blog.csdn.net/qq_35221977/article/details/137171497 脚本 chcp 65001 echo 建立vite工程 set PRO_NAMEmy-vue-appif not exist %PRO_NAME% (call npm i…

vue使用路由技术实现登录成功后跳转到首页

文章目录 一、概述二、使用步骤安装vue-router在src/router/index.js中创建路由器&#xff0c;并导出在vue应用实例中使用router声明router-view标签&#xff0c;展示组件内容 三、配置登录成功后跳转首页四、参考资料 一、概述 路由&#xff0c;决定从起点到终点的路径的进程…

day20-线性表(链表II)

一、调试器 1.1 gdb&#xff08;调试器&#xff09; 在程序指定位置停顿 1.1.1 一般调试 gcc直接编译生成的是发布版&#xff08;Release&#xff09; gcc -g //-g调式版本&#xff0c;&#xff08;体积大&#xff0c;内部有源码&#xff09;&#xff08;DeBug&#…

HTTP 连接复用机制详解

文章目录 HTTP 连接复用机制详解为什么需要连接复用&#xff1f;连接复用的实现方式HTTP/1.1 的 Keep-AliveHTTP/2 多路复用 HTTP/1.1 的队头阻塞问题 HTTP 连接复用机制详解 HTTP 连接复用是 HTTP/1.1 及更高版本中的核心优化机制&#xff0c;旨在减少 TCP 连接建立和关闭的开…

网络协议分析 实验六 TCP和端口扫描

文章目录 实验6.1 TCP(Transfer Control Protocol)练习二 利用仿真编辑器编辑并发送TCP数据包实验6.2 UDP端口扫描实验6.3 TCP端口扫描练习一 TCP SYN扫描练习二 TCP FIN扫描 实验6.1 TCP(Transfer Control Protocol) 建立&#xff1a;syn,syn ack,ack 数据传送&#xff1a;tcp…

Spring Web MVC————入门(2)

1&#xff0c;请求 我们接下来继续讲请求的部分&#xff0c;上期将过很多了&#xff0c;我们来给请求收个尾。 还记得Cookie和Seesion吗&#xff0c;我们在HTTP讲请求和响应报文的时候讲过&#xff0c;现在再给大家讲一遍&#xff0c;我们HTTP是无状态的协议&#xff0c;这次的…

每日算法-250514

每日算法学习记录 (2024-05-14) 今天记录三道 LeetCode 算法题的解题思路和代码。 1. 两数之和 题目截图: 解题思路 这道题要求我们从一个整数数组中找出两个数&#xff0c;使它们的和等于一个给定的目标值 target&#xff0c;并返回这两个数的下标。 核心思路是使用 哈希…

嵌入式培训之数据结构学习(三)gdb调试、单向链表练习、顺序表与链表对比

目录 一、gdb调试 &#xff08;一&#xff09;一般调试步骤与命令 &#xff08;二&#xff09;找段错误&#xff08;无下断点的地方&#xff09; &#xff08;三&#xff09;调试命令 二、单向链表练习 1、查找链表的中间结点&#xff08;用快慢指针&#xff09; 2、找出…

虚拟机安装CentOS7网络问题

虚拟机安装CentOS7网络问题 1. 存在的问题1.1 CentOS7详细信息 2. 解决问题3.Windows下配置桥接模式 1. 存在的问题 虽然已经成功在虚拟机上安装了CentOS7&#xff0c;但是依旧不能上网。 1.1 CentOS7详细信息 [fanzhencentos01 ~]$ hostnamectlStatic hostname: centos01Ic…

迅为RK3588开发板安卓GPIO调用APP运行测试

将网盘上的安卓工程文件复制到 Windows 电脑上。确保工程路径中使用英文字符&#xff0c;不包含中文。接着&#xff0c;启动 Android Studio&#xff0c;点击“Open”按钮选择应用工程文件夹&#xff0c;然后点击“OK”。由于下载 Gradle 和各种 Jar 包可能需要一段时间&#x…

Unity 红点系统

首先明确一个&#xff0c;即红点系统的数据结构是一颗树&#xff0c;并且红点的数据结构的初始化需要放在游戏的初始化中&#xff0c;之后再是对应的红点UI侧的注册&#xff0c;对应的红点UI在销毁时需要注销对红点UI的显示回调注册&#xff0c;但是不销毁数据侧的红点注册 - …

尼康VR镜头防抖模式NORMAL和ACTIVE的区别(私人笔记)

1. NORMAL 模式&#xff08;常规模式&#xff09; 适用场景&#xff1a;一般手持拍摄&#xff0c;比如人像、静物、风景或缓慢平移镜头&#xff08;如水平追拍&#xff09;等。工作特性&#xff1a; 补偿手抖引起的小幅度震动&#xff08;比如手持时自然的不稳&#xff09;&am…

从索引中排除 Elasticsearch 字段

作者&#xff1a;来自 Elastic Kofi Bartlett 说明如何配置 Elasticsearch 排除字段、为什么要这样做&#xff0c;以及应遵循的最佳实践。 更多阅读&#xff1a;Elasticsearch&#xff1a;inverted index&#xff0c;doc_values 及 source 想获得 Elastic 认证&#xff1f;了解…

超详细Docker教程

前言&#xff1a;大家在在Linux上部署mysql及其他软件时&#xff0c;大家想一想自己最大的感受是什么&#xff1f; 我相信&#xff0c;除了个别天赋异禀的人以外&#xff0c;大多数人都会有相同的感受&#xff0c;那就是麻烦。核心体现在三点&#xff1a; 命令太多了&#xff…

Java项目拷打(外卖+点评)

一、点评星球&#xff08;黑马点评&#xff09; 1、项目概述 1.1、项目简介 本项目是基于Spring Boot与Redis深度整合的前后端分离的点评平台。系统以Redis为核心技术支撑&#xff0c;重点解决高并发场景下的缓存穿透、击穿、雪崩等问题&#xff0c;涵盖商户展示、优惠券秒杀…

微信小程序仿淘宝拍照/照片点位识图、点位裁剪生图、图片裁剪组件、图片点位框选、裁剪生成图片,canvasToImg

实现效果 效果&#xff1a; 1.微信小程序仿淘宝拍照/照片点位识图、根据点位裁剪生图、图片可裁剪、图片高度可控 2.识别点位自动生成标准构图方案&#xff0c;支持手动微调实现像素级精准裁剪 3.可以根据接口识别的点位信息实现拍照/相册图片特征点自动识别并裁剪 实现步骤 …

Qt/C++开发监控GB28181系统/录像文件查询/录像回放/倍速播放/录像文件下载

一、前言 搞定了实时预览后&#xff0c;另一个功能就是录像回放&#xff0c;录像回放和视频点播功能完全一致&#xff0c;唯一的区别就是发送点播的sdp信息中携带了开始时间和结束时间&#xff0c;因为是录像文件&#xff0c;所以有这个时间&#xff0c;而实时视频预览这个对应…

季报中的FPGA行业:U型反转,春江水暖

上周Lattice,AMD两大厂商相继发布2025 Q1季报,尽管恢复速度各异,但同时传递出FPGA行业整体回暖的复苏信号。 5月5日,Lattice交出了“勉强及格”的答卷,报告季度营收1亿2000万,与华尔街的预期基本相符。 对于这家聚焦在中小规模器件的领先厂商而言,按照其CEO的预期,长…

嵌入式机器学习平台Edge Impulse图像分类 – 快速入门

陈拓 2025/05/08-2025/05/11 1. 简介 官方网址 https://edgeimpulse.com/ 适用于任何边缘设备的人工智能&#xff1a; Gateways - 网关 Sensors & Cameras - 传感器和摄像头 Docker Containers - Docker容器 MCUs, NPUs, CPUs, GPUs 构建数据集、训练模型并优化库以…