解析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是被驱动表。
这里会扫描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的字段在被驱动表没有建立索引
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的索引结构有了一定的了解,
如果没有的话,可以去看下:通过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


猜你喜欢
- 魔法方法凡是在类内部定义,以“__开头__结尾”的方法都称之为魔法方法,又称“类的内置方法”, 这些方法会在某些条件成立时触发。经常用到的双
- 环境配置系统:Windows10版本:python 3.8Turtle扫盲1.绘图窗体的设置turtle.setup(width, heig
- ACCESS2000文件用ACCESS2007打开,并迁移到SQLSERVER2005里 打开ACCESS2007的数据库工具方法
- 我使用Pytorch进行模型训练时发现真正模型本身对于显存的占用并不明显,但是对应的转换为tensorflow后(权重也进行了转换),发现P
- Anaconda下需要使用Python与MySQL数据库进行交互,所以需要import一个mysql-python的包,但是在ipython
- 本教程使用python来生成随机漫步数据,再使用matplotlib将数据呈现出来开发环境操作系统: Windows10 IDE: Pych
- 你是怎么把密码储存到数据库里?是以纯文字的方式?你可知道这对安全的危险性?当攻击你网站的人能开启数据库浏览,以纯文字方式存在数据库里的密码一
- 揭秘一个普通的输入框背后惊人的秘密。某月某日,某项目某页面,需要一个价格区间筛选功能,需求合理,所以设计做上去。这是一个无比普通的输入框。在
- 前言福宝们,下午好啊。改版后的第4.5章阅读量有点少呀,不知道是不是拖更了一天的缘故。呜呜呜,以后一定要做个不拖更的好熊,所以今天继续爆肝第
- 上文: 《IE7的web标准之道——1:前言(兼目录)》IE历来被web标准的拥护者所诟病,而当FireFox横空出世以后,更多的网页制作者
- 一般用 createProcessingInstruction 方法创建处理指令指定参数为 "xml","ve
- 有框计算器这个计算器我们用到了Python自带的Tkinter库# 导入tkinter库import tkinter我们要对窗口进行一些基本
- 本文实例讲述了C#基于SQLiteHelper类似SqlHelper类实现存取Sqlite数据库的方法。分享给大家供大家参考。具体如下:这个
- 代码如下: EXEC sp_rename '表名.[原列名]', '新列名', 'column
- 从最基础的说起。本教程中,所有IE 均指 WindowXP + IE 6.0, 所有 FF 均指 FF 1.5。1. 不用编程的部分1.1
- 本文实例为大家分享了python使用turtle库绘制树的具体代码,供大家参考,具体内容如下# -*- coding: utf-8 -*-&
- 一、MYSQL的索引索引(Index):帮助Mysql高效获取数据的一种数据结构。用于提高查找效率,可以比作字典。可以简单理解为排好序的快速
- 计模式的目的是让代码易维护、易扩展,不能为了模式而模式,因此一个简单的工具脚本是不需要用到任何模式的。简单工厂模式又叫静态工厂方法模式,工厂
- Tensorflow数据读取有三种方式:Preloaded data: 预加载数据Feeding: Python产生数据,再把数据喂给后端。
- asp生成wbmp代码如下: <%@ Language=VBScript %><%Funct