【MySQL精通之路】SQL优化(1)-查询优化(7)-嵌套循环联接

embedded/2024/12/22 2:39:07/

主博客:

【MySQL精通之路】SQL优化(1)-查询优化-CSDN博客

上一篇:

【MySQL精通之路】SQL优化(1)-查询优化(6)-索引条件下推-CSDN博客

下一篇:


1.嵌套循环连接算法

一个简单的嵌套循环联接(NLJ)算法一次从循环中的第一个表中读取一行,将每一行传递给一个嵌套循环,该嵌套循环处理联接中的下一个表。只要有剩余的表要联接,这个过程就会重复多次。

请把上面这句话熟记于心~

假设三个表t1、t2和t3之间的联接将使用以下联接类型来执行:

sql">Table   Join Type
t1      range
t2      ref
t3      ALL

如果使用简单的NLJ算法,则连接的处理方式如下:

sql">for each row in t1 matching range {for each row in t2 matching reference key {for each row in t3 {if row satisfies join conditions, send to client}}
}

因为NLJ算法一次一行地从外循环传递到内循环,所以它通常会多次读取在内循环中处理的表

2.块嵌套循环连接算法

嵌套循环(BNL)联接算法使用外部循环中读取的行的缓冲减少必须读取内部循环中的表的次数。例如,如果将10行读取到缓冲器中,并且将缓冲器传递到下一个内部循环,则可以将内部循环中读取的每一行与缓冲器中的所有10行进行比较。这将使必须读取内部表的次数减少一个数量级

在MySQL 8.0.18之前,当不能使用索引时,此算法适用于等联接

在MySQL 8.0.18及更高版本中,这种情况下会使用哈希连接优化

从MySQL 8.0.20开始,MySQL不再使用块嵌套循环,并且在所有以前使用块嵌套循环的情况都使用Hash联接替代

请参阅“哈希连接优化”。

【MySQL精通之路】SQL优化(1)-查询优化(4)-Hash联接查询-CSDN博客

2.1 MySQL联接缓冲具有以下特点:

当联接类型为ALL索引(换言之,当不能使用可能的键,并且分别对数据行索引行进行了完全扫描)或范围查询时,可以使用联接缓冲

缓冲的使用也适用于外部联接,如“块嵌套循环和批量密钥访问联接”所述。

联接缓冲区永远不会分配给第一个非常量表,即使它的类型是ALLindex

只有联接查询相关的列存储在联接缓冲区中,而不是整行。

join_buffer_size系统变量确定用于处理查询的每个联接缓冲区的大小。

为每个可以缓冲的联接分配一个缓冲区,因此可以使用多个联接缓冲区来处理给定的查询。

联接缓冲区在执行联接之前分配,在查询完成后释放。

对于前面为NLJ算法描述的示例联接(无缓冲),使用联接缓冲按如下方式进行联接:

sql">for each row in t1 matching range {for each row in t2 matching reference key {store used columns from t1, t2 in join bufferif buffer is full {for each row in t3 {for each t1, t2 combination in join buffer {if row satisfies join conditions, send to client}}empty join buffer}}
}if buffer is not empty {for each row in t3 {for each t1, t2 combination in join buffer {if row satisfies join conditions, send to client}}
}

如果S是连接缓冲器中存储的每个t1、t2组合的大小,而C是缓冲器中组合的数量,则扫描次数表t3为:

(S * C)/join_buffer_size + 1

 t3扫描的次数随着join_buffer_size的值的增加而减少,直到join_buffer _size足够大以容纳所有先前的行组合为止,这时,空间变大不会获得更多增益。


http://www.ppmy.cn/embedded/44037.html

相关文章

LeetCode:78.子集

解答 class Solution:def subsets(self, nums: List[int]) -> List[List[int]]:res[[]]for i in nums:res[[i]num for num in res]return res代码解释 这段代码定义了一个名为Solution的类,并在其中定义了一个名为subsets的方法。该方法接受一个整数列表nums作…

编程中的模块迷宫:区分与正确使用

新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一、模块混淆的陷阱 二、碳模块与探母模块的区别 三、如何正确使用模块 四、代码示例 五…

模拟集成电路(5)----单级放大器(共栅级)

模拟集成电路(5)----单级放大器(共栅级) 有一些场合需要一些小的输入电阻(电流放大器) 大信号分析 − W h e n V i n ≥ V B − V T H ∙ M 1 i s o f f , V o u t V D D − F o r L o w e r V i n I d 1 2 μ n C o x W L ( V…

服务器内存与CPU要占用多少才合理?

一 通常服务器内存占用多少合理?cpu占用多少才合理? 1 通常配置范围建议: 建议CPU使用率不高于80%;内存使用率不高于80%; 注意:具体情况还需要根据服务器的实际负载和应用场景来判断。 2 内存使用率&…

【Linux 网络编程】网络的基础知识详解!

文章目录 1. 计算机网络背景2. 认识 "协议" 1. 计算机网络背景 网络互联: 多台计算机连接在一起, 完成数据共享; 🍎局域网(LAN----Local Area Network): 计算机数量更多了, 通过交换机和路由器连接。 🍎 广域网WAN: 将…

JAVA:Random详解

Java中的java.util.Random类用于生成伪随机数。它提供了多种方法来生成不同类型的随机数,包括整数、浮点数和布尔值。以下是对Random类及其主要方法的详细介绍 一、生成随机数 创建一个Random对象,可以使用以下两种方式: 无参构造函数&…

基于CNN卷积神经网络的金融数据预测matlab仿真,对比BP,RBF,LSTM

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 反向传播网络(BP,多层感知器MLP) 4.2 径向基函数网络(RBF) 4.3 卷积神经网络(CNN) 4.4 长短期记忆网…

【Daily Code】leetcode2951. 找出峰值

Problem: 2951. 找出峰值 Code class Solution { public:vector<int> findPeaks(vector<int>& mountain) {int n mountain.size();vector<int> res;for(int i 1; i < n - 1; i ) {if(mountain[i] > mountain[i - 1] && mountain[i] >…