解析MySQL join查询的原理

作者:CaptainCats 时间:2024-01-17 13:28:46 

MySQL用Nested-Loop Join算法实现join查询

区分驱动表和被驱动表,以驱动表的结果集为循环的基础,访问被驱动表过滤数据,然后合并结果,驱动表在外循环、被驱动表在内循环。
如果还有第三张参与join查询的表,则以合并的结果为驱动表,第三张表作为被驱动表,以此类推。

left join中的左表是驱动表、右表是被驱动表,right join刚好相反。

Nested-Loop Join有三种实现

SNLJ

Simple Nested-Loop Join

假设A是驱动表,B是被驱动表。

解析MySQL join查询的原理

这里会扫描A表,用A的结果集作为外循环,
每循环一次,会扫描B表一遍(遍历内循环)

A表有N行,B表有M行。

SNLJ的开销如下(最大情况下):

扫描A表1次;
扫描B表N次。
总共读取记录数:N + N * M。

为了专注于理解Nested-Loop Join,这里不讨论带where子句的情况,以下相同。

BNLJ

Block Nested-Loop Join

假设A是驱动表,B是被驱动表。

用来join的字段在被驱动表没有建立索引

解析MySQL join查询的原理

Join Buffer
MySQL会将驱动表结果集中(多条记录)用来join的字段缓存到Join Buffer,
Join Buffer的特点是只需要扫描被驱动表一次,就能得到Join Buffer中所有记录的匹配结果,
减少扫描的次数。

Join Buffer默认大小256k,会生成n-1个Join Buffer缓冲区,n为参与join查询的表数量。

A表有N行,B表有M行。

BNLJ的开销如下(最大情况下):

扫描A表1次;
扫描B表X次;
X的大小取决于N、join字段的大小、Join Buffer的大小,通常X<<N。

INLJ

Index Nested-Loop Join

假设A是驱动表,B是被驱动表。

用来join的字段在被驱动表建立了索引

聚集索引

解析MySQL join查询的原理

非聚集索引

解析MySQL join查询的原理

在这里我们假设您已对MySQL的索引结构有了一定的了解,
如果没有的话,可以去看下:通过B+Tree平衡多叉树理解InnoDB引擎的聚集和非聚集索引

这里会扫描A表,用A的结果集作为外循环,
然后通过B表的索引来检索,不会遍历B表。

A表有N行,B表有M行。

INLJ的开销如下(最大情况下):

扫描A表1次;
通过B表索引检索N次,成本比扫描B表N次会低很多;
回表:先找到非聚集索引,再找到聚集索引,会多一次磁盘IO。

NLJ优先级

INLJ>BNLJ>SNLJ

如何优化join查询效率

尽量将小表作为驱动表,大表作为被驱动表;
为参加join的字段在被驱动表建立聚集索引,其次是非聚集索引;
尽可能减少join的字段数量,或者使用长度比较小的字段来join,这样Join Buffer一次可以缓存更多条记录。

inner join时,MySQL会自动将小表作为驱动表,大表作为被驱动表。

扫描整张表是成本非常高的操作。

来源:https://blog.csdn.net/qq_35549286/article/details/122690332

标签:MySQL,join,查询
0
投稿

猜你喜欢

  • python+selenium定时爬取丁香园的新型冠状病毒数据并制作出类似的地图(部署到云服务器)

    2022-12-31 16:20:14
  • js正则表达式验证密码强度【推荐】

    2024-04-29 13:39:30
  • Python灰度变换中灰度切割分析实现

    2021-10-05 12:07:49
  • 浅谈哪个Python库才最适合做数据可视化

    2022-12-05 00:34:58
  • Oracle数据库安全策略分析 (三)

    2010-07-31 13:24:00
  • python paramiko利用sftp上传目录到远程的实例

    2023-08-10 02:53:23
  • 对python当中不在本路径的py文件的引用详解

    2022-12-17 15:12:42
  • Pytorch 保存模型生成图片方式

    2023-04-20 17:42:17
  • xhtml有哪些块级元素

    2009-12-06 11:58:00
  • 如何制作一个从Access数据库中读取记录的下拉菜单?

    2010-06-29 21:23:00
  • 如何在pyqt中实现全局事件实战记录

    2023-07-01 02:25:46
  • 详解django的serializer序列化model几种方法

    2022-12-06 00:40:08
  • Python拼接字符串的7种方法总结

    2022-10-28 08:38:00
  • MySQL中表分区技术详细解析

    2024-01-21 01:01:11
  • 通过不同的CSS设计字体大小来提高用户体验

    2008-12-10 19:17:00
  • 如何基于线程池提升request模块效率

    2023-06-12 11:13:44
  • Python如何读写二进制数组数据

    2022-01-12 19:35:57
  • python实现无边框进度条的实例代码

    2023-07-23 05:22:59
  • Python pomegranate库实现基于贝叶斯网络拼写检查器

    2021-06-17 19:27:51
  • python sorted函数的小练习及解答

    2021-10-14 15:50:28
  • asp之家 网络编程 m.aspxhome.com