广告
返回顶部
首页 > 资讯 > 数据库 >Mysql Join语句执行流程
  • 803
分享到

Mysql Join语句执行流程

MysqlJoin语句执行流程 2018-10-17 09:10:09 803人浏览 才女
摘要

JOIN主要使用 Index Nested-Loop Join 和 Block Nested-Loop Join 算法实现 Index Nested-Loop Join 如果 join on 相关的字段存在索引就使用 Index Nes

Mysql Join语句执行流程

JOIN主要使用 Index Nested-Loop Join 和 Block Nested-Loop Join 算法实现

Index Nested-Loop Join

如果 join on 相关的字段存在索引就使用 Index Nested-Loop Join 算法来进行关联

如下sql语句的执行过程:

select * from t1 join t2 on (t1.a=t2.a);
  1. 对驱动表 t1 做了全表扫描,这个过程需要扫描 100 行;
  2. 而对于每一行 R,根据 a 字段去表 t2 查找,走的是树搜索过程。由于我们构造的数据 都是一一对应的,因此每次的搜索过程都只扫描一行,也是总共扫描 100 行;
  3. 所以,整个执行流程,总扫描行数是 200。

假设不使用 join,那我们就只能用单表查询。我们看看上面这条语句的需求,用单表查询 怎么实现。

  1. 执行select * from t1,查出表 t1 的所有数据,这里有 100 行;
  2. 循环遍历这 100 行数据: 从每一行 R 取出字段 a 的值 $R.a; 执行select * from t2 where a=$R.a; 把返回的结果和 R 构成结果集的一行。

可以看到,在这个查询过程,也是扫描了 200 行,但是总共执行了 101 条语句,比直接 join 多了 100 次交互。除此之外,客户端还要自己拼接 SQL 语句和结果

显然,这么做还不如直接 join 好。

怎么选择驱动表?

假设驱动表的行数是 N,执行过程就要扫描驱动表 N 行,然后对于每一行,到被驱动表上匹配一次

因此整个执行过程,近似复杂度是 N + N2log2M。显然,N 对扫描行数的影响更大,因此应该让小表来做驱动表

结论:

  1. 使用 join 语句,性能比强行拆成多个单表执行 SQL 语句的性能要好;
  2. 如果使用 join 语句的话,需要让小表做驱动表。

但是,你需要注意,这个结论的前提是“可以使用被驱动表的索引”。

Block Nested-Loop Join

如果关联语句中没有索引的话 可能需要扫描 N*M 行 当然Mysql对此有一个优化算法

算法的流程是这样的:

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

Block Nested-Loop Join 算法的这 N*M 次判断是内存操作,速度上会快很多,性能也更好

接下来,我们来看一下,在这种情况下,应该选择哪个表做驱动表。

  1. 两个表都做一次全表扫描,所以总的扫描行数是 M+N;
  2. 内存中的判断次数是 M*N。

可以看到,调换这两个算式中的 M 和 N 没差别,因此这时候选择大表还是小表做驱动 表,执行耗时是一样的。

join_buffer 放不下怎么办

如果放不下表 t1 的所有数据话,策略很简单,就是分段放

执行过程就变成了:

  1. 扫描表 t1,顺序读取数据行放入 join_buffer 中,放完第 88 行 join_buffer 满了,继续第 2 步;
  2. 扫描表 t2,把 t2 中的每一行取出来,跟 join_buffer 中的数据做对比,满足 join 条件 的,作为结果集的一部分返回;
  3. 清空 join_buffer;
  4. 继续扫描表 t1,顺序读取最后的 12 行数据放入 join_buffer 中,继续执行第 2 步

假设,驱动表的数据行数是 N,需要分 K 段才能完成算法流程,被驱动表的数据行数是 M。 注意,这里的 K 不是常数,N 越大 K 就会越大,因此把 K 表示为λ*N,显然λ的取值范围 是 (0,1)。 所以,在这个算法的执行过程中:

  1. 扫描行数是 N+λ* N*M;
  2. 内存判断 N*M 次。

显然,内存判断次数是不受选择哪个表作为驱动表影响的。而考虑到扫描行数,在 M和 N大小确定的情况下,N小一些,整个算式的结果会更小。

所以结论是,应该让小表当驱动表。

这里我需要说明下,什么叫作“小表”。

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

join语句怎么优化

Multi-Range Read 优化

在介绍 join 语句的优化方案之前,我需要先介绍一个知识点,即:Multi-Range Read 优化 (MRR)。这个优化的主要目的是尽量使用顺序读盘

因为大多数的数据都是按照主键递增顺序插入得到的,所以我们可以认为,如果按照主键 的递增顺序查询的话,对磁盘的读比较接近顺序读,能够提升读性能

这,就是 MRR 优化的设计思路。此时,语句的执行流程变成了这样:

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

另外需要说明的是,如果你想要稳定地使用 MRR 优化的话,需要设置

set optimizer_switch="mrr_cost_based=off"

MRR 能够提升性能的核心在于,这条查询语句在索引 a 上做的是一个范围查询可以得到足够多的主键 id。这样通过排序以后,再去主键索引查数据,才能体现出“顺序性”的优势

Batched Key Access

这个 Batched Key Access (BKA),其实就是对 NLJ 算法的优化

NLJ 算法执行的逻辑是:从驱动表 t1,一行行地取出 a 的值,再到被驱动表 t2 去做 join。也就是说,对于表 t2 来说,每次都是匹配一个值。这时,MRR 的优势就用不上了

那怎么才能一次性地多传些值给表 t2呢?方法就是,从表 t1 里一次性地多拿些行出来, 一起传给表 t2。 既然如此,我们就把表t1 的数据取出来一部分,先放到 join_buffer。 我们知道 join_buffer 在 BNL 算法里的作用,是暂存驱动表的数据。但是在 NLJ 算法里并没有用。那么,我们刚好就可以复用 join_buffer 到 BKA 算法中。

如果要使用 BKA 优化算法的话,你需要在执行 SQL 语句之前,先设置

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

BNL 算法的性能问题

大表 join 操作虽然对 io 有影响,但是在语句执行结束后,对 IO 的影响也就结束了。但是,对 Buffer Pool 的影响就是持续性的,需要依靠后续的查询请求慢慢恢复内存命中率

为了减少这种影响,你可以考虑增大 join_buffer_size 的值,减少对被驱动表的扫描次数。

也就是说,BNL 算法对系统的影响主要包括三个方面:

  1. 可能会多次扫描被驱动表,占用磁盘 IO 资源;
  2. 判断 join 条件需要执行 M*N 次对比(M、N 分别是两张表的行数),如果是大表就会占用非常多的 CPU 资源;
  3. 可能会导致 Buffer Pool 的热数据被淘汰,影响内存命中率

我们执行语句之前,需要通过理论分析和查看 explain 结果的方式,确认是否要使用 BNL 算法。如果确认优化器会使用 BNL 算法,就需要做优化。优化的常见做法是,给被驱动表 的 join 字段加上索引,把 BNL 算法转成 BKA 算法

hash join

如果 join_buffer 里面维护的不是一个无序数组,而是一个哈希表的话,那么就不是 10 亿次判 断,而是 100 万次 hash 查找。这样的话,整条语句的执行速度就快多了吧?

实际上,这个优化思路,我们可以自己实现在业务端。实现流程大致如下:

  1. select * from t1;取得表 t1 的全部 1000 行数据,在业务端存入一个 hash 结构
  2. select * from t2 where b>=1 and b<=2000; 获取表 t2 中满足条件的 2000 行 数据。
  3. 把这 2000 行数据,一行一行地取到业务端,到 hash 结构的数据表中寻找匹配的数据。满足匹配的条件的这行数据,就作为结果集的一行。
您可能感兴趣的文档:

--结束END--

本文标题: Mysql Join语句执行流程

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

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

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

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

下载Word文档
猜你喜欢
  • Mysql Join语句执行流程
    JOIN主要使用 Index Nested-Loop Join 和 Block Nested-Loop Join 算法实现 Index Nested-Loop Join 如果 join on 相关的字段存在索引就使用 Index Nes...
    99+
    2018-10-17
    Mysql Join语句执行流程
  • MySQL之Join语句执行流程是什么
    本文小编为大家详细介绍“MySQL之Join语句执行流程是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“MySQL之Join语句执行流程是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。Join语句执行流...
    99+
    2023-07-05
  • MySQL实战教程之Join语句执行流程
    目录Join语句执行流程一、Index Nested-Loop Join二、Simple Nested-Loop Join三、block Nested-Loop Join四、总结Join语句执行流程 Hi,我是阿昌,今天...
    99+
    2023-03-06
    mysqlJoin语句 mysqlJoin
  • Mysql 更新语句执行流程
    与查询流程不一样的是,更新流程涉及两个重要的日志模块,redo log和 binlog redo log 如果每一次的更新操作都需要写进磁盘,然后磁盘也 要找到对应的那条记录, 然后再更新,整个过程 IO 成本、查找成本都很高 Mysql使...
    99+
    2014-08-15
    Mysql 更新语句执行流程
  • mysql的sql语句执行流程
    1、client和server建立连接,client发送sql至server(对应连接器这一过程) 2、server如果在查询缓存中发现了该sql,则直接使用查询缓存的结果返回给client,如果查询缓存中...
    99+
    2022-10-18
  • mysql中SQL语句的执行流程
    今天就跟大家聊聊有关mysql中SQL语句的执行流程,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。       &n...
    99+
    2022-10-18
  • MySQL执行SQL语句的流程详解
    目录1、通常sql执行流程1.1 问题1:mysql谁去处理网络请求?1.2 问题2:MySQL如何执行sql语句?1.3 查询解析器1.4 查询优化器1.5 存储引擎1.6 执行器2、总结1、通常sql执行流程 用户...
    99+
    2022-09-25
  • MySQL查询语句执行流程是什么
    这篇“MySQL查询语句执行流程是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“MySQL查询语句执行流程是什么”文章吧...
    99+
    2023-07-05
  • mysql查询语句中,是join先执行还是where先执行?
    在 MySQL 中,WHERE 子句会先于 JOIN 子句执行。 JOIN 子句用于连接两个或多个表,在 JOIN 子句中可以使用 ON 或 USING 子句来指定连接条件。 JOIN 子句会从两个表中返回符合连接条件的行,这些...
    99+
    2023-09-05
    mysql 数据库 sql mybatis
  • mysql中执行查询语句的流程分析
    这篇文章给大家分享的是有关mysql中执行查询语句的流程分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。比如,在我们从student表中查询一个id=2的信息selec ...
    99+
    2022-10-18
  • mysql查询语句join、on、where的执行顺序
    目录一、典型SELECT语句完整的执行顺序二、from三、on四、on 条件与where 条件1、使用位置2、使用对象3、选择与使用五、join 流程mysql 的执行顺序 一、典型SELECT...
    99+
    2022-11-19
    mysql查询语句执行顺序 mysql join mysql on mysql where
  • MySQL中SQL语句执行流程是怎么样的
    这篇文章主要介绍MySQL中SQL语句执行流程是怎么样的,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!总的来说,MySQL逻辑架构可以分为server层和存储引擎层这两个部分。这篇文...
    99+
    2022-10-18
  • mysql语句执行顺序
    思考: 大家可以思考一下下面sql语句写的有没有问题? select jg.id as goodsId,jm.name,... from jdy_merchant jm left outer join jdy_expr...
    99+
    2018-12-02
    mysql语句执行顺序
  • Mysql查询语句执行过程 - G
    Mysql查询语句执行过程   Mysql分为server层和存储引擎两部分,或许可以再加一层连接层   连接层(器) Mysql使用的是典型的C/S架构。连接器通过典型的TCP握手完成连接。 需要注的是, 如果用户名和密码都正确...
    99+
    2021-12-15
    Mysql查询语句执行过程 - G
  • Mysql 优化LEFT JOIN语句
    1.首先说一下个人对LEFT JOIN 语句的看法,原先我是没注意到LEFT JOIN 会影响到性能的,因为我平时在项目开发中,是比较经常见到很多个关联表的语句的。 2.阿里巴巴手册说过,连接表的语句...
    99+
    2023-08-31
    mysql 数据库
  • C语言switch case语句的执行流程是什么
    C语言的switch case语句的执行流程如下:1. 首先,计算switch语句中的表达式的值。2. 根据表达式的值,程序将跳转到...
    99+
    2023-09-20
    C语言
  • Mysql 执行流程
    1、逻辑剖析 sql 执行流程为:sql语句 -> 查询缓存 -> 解析器 -> 优化器 -> 执行器。 1.1 服务器处理客户端请求 ​ 客户端程序 connectors >> 连接池 >> SQL接口 >> 解析器 >> 优化器 ...
    99+
    2020-07-21
    Mysql 执行流程
  • 深入理解:Mysql执行SQL语句过程
     开发人员基本都知道,我们的数据存在数据库中(目前最多的是mysql和oracle,由于作者更擅长mysql,所以这里默认数据库为mysql),服务器通过sql语句将查询数据的请求传入到mysql数据库。数据库拿到sql语句以后。...
    99+
    2023-06-02
  • MySql中sql语句执行过程是什么
    今天小编给大家分享一下MySql中sql语句执行过程是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。sql语句的执行过程...
    99+
    2023-07-05
  • MySQL执行一条查询语句的过程
      执行流程 如下图所示,我们可以看到当向 MySQL 发送一个请求时,MySQL 到底做了什么:   客户端发送一条査询给服务器。 服务器先检查査询缓存,如果命中了缓存,则立刻返回存储在缓存中的结果。否则进人下一阶段。 服务器端进...
    99+
    2018-04-18
    MySQL执行一条查询语句的过程
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作