前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >MySQL 8.0 OCP (1Z0-908) 考点精析-性能优化考点5:表连接算法(join algorithm)

MySQL 8.0 OCP (1Z0-908) 考点精析-性能优化考点5:表连接算法(join algorithm)

作者头像
SQLplusDB
发布于 2023-08-17 01:13:22
发布于 2023-08-17 01:13:22
54300
代码可运行
举报
运行总次数:0
代码可运行

MySQL表连接的算法

我们知道对于Oracle的表连接,根据SQL连接条件主要支持如下三种连接方法(算法):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
- 嵌套循环连接(Nested Loops Joins)
- 哈希连接(Hash Joins)
- 排序合并连接(Sort Merge Joins)

对于MySQL而言,支持的连接算法主要包括如下两种:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
- 嵌套循环连接(Nested Loops Joins)
- 哈希连接(Hash Joins)

对于嵌套循环连接(Nested Loops Joins),又可以分为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
- 简单嵌套循环连接(Simple  Nested-Loop Join Algorithm)
- 块嵌套循环连接(Block Nested-Loop Join Algorithm,BNL)
- 批量键值访问连接(Batched Key Access Joins,BKA

嵌套循环连接(Nested Loops Joins)

简单嵌套循环连接(Simple Nested-Loop Join Algorithm)

对于进行嵌套循环连接的两个表,可以分别称为外部表(驱动表)和内部表。

进行简单嵌套循环连接(Simple Nested-Loop Join Algorithm)时候,会读取外部表(驱动表)中的一条记录,然后根据连接条件扫描内部表,反复循环,直到遍历完驱动表所有满足谓词条件的记录。

例:对于如下t1、t2、t3三个表的连接来说,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Table   Join Type
t1      range
t2      ref
t3      ALL

简单嵌套循环连接算法的伪代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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
    }
  }
}
块嵌套循环连接(Block Nested-Loop Join Algorithm, BNL)

简单嵌套循环连接需要反复读取多次内部表(扫描内部表次数相当于驱动表中所有满足谓词条件的记录)。

块嵌套循环连接对这种连接算法进行了优化,在读取驱动表(外部表)时,一次性缓存多条驱动表的记录到 Join Buffer,然后拿Join Buffer中的记录批量与内层循环读取的记录进行匹配。BNL一般用于内连接。

通过块嵌套循环连接可以大大降低对内部表的扫描次数。

对于前面例中t1、t2、t3三个表的连接来说,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Table   Join Type
t1      range
t2      ref
t3      ALL

块嵌套循环连接算法的伪代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for each row in t1 matching range {
  for each row in t2 matching reference key {
    store used columns from t1, t2 in join buffer
    if 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
    }
  }
}

参考: Block Nested-Loop Join Algorithm https://dev.mysql.com/doc/refman/8.0/en/nested-loop-joins.html

连接缓冲区(join buffer)及join_buffer_size参数

每个进程的连接缓冲区(join buffer)的大小由系统环境变量join_buffer_size控制。

Command-Line Format

–join-buffer-size=#

System Variable

join_buffer_size

Scope

Global, Session

Dynamic

Yes

SET_VAR Hint Applies

Yes

Type

Integer

Default Value

262144

Minimum Value

128

Maximum Value (Windows)

4294967168

Maximum Value (Other, 64-bit platforms)

18446744073709551488

Maximum Value (Other, 32-bit platforms)

4294967168

Unit

bytes

Block Size

128

join_buffer_size是用于控制普通索引扫描、范围索引扫描和不使用索引的连接(全表扫描)的缓冲区的最小大小。 MySQL 8.0.18及更高版本中,join_buffer_size变量还用于控制哈希连接使用的内存量。

使用块嵌套循环(BNL)时,较大的连接缓冲区意味着可以将驱动表(外部表)的所有行都存储在连接缓冲区中; 使用块嵌套循环(BNL)时,较大的连接缓冲区意味着对连接操作的右侧表进行的顺序访问就越多。 因此,增加join_buffer_size的大小在某些情况下可以显着提高性能。

但是,增加join_buffer_siz意味着增大进程的内存缓冲区大小,如果全局设置的比较大,可能导致内存分配时间时间长,进而导致性能大幅下降。所以建议全局设置保持较小,仅在执行大型连接的会话中将会话级别的值设置为较大值(或者使用/*+ SET_VAR(join_buffer_size= XX) */提示针对个别SQL设置较大值)。

参考: join_buffer_size https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_join_buffer_size

块嵌套循环连接(Block Nested-Loop Join Algorithm, BNL)扩展

随着MySQL数据库的演进,MySQL对块嵌套循环(BNL)连接算法进行了扩展,扩展后的块嵌套循环(BNL)连接算法,不仅可以用于内连接,还可以用于外连接、半连接和嵌套外连接。

  • 当使用连接缓冲区(join buffer)执行这些操作时,放入缓冲区的每一行都会被赋予一个匹配标志。
  • 外连接操作时,根据条件检查【要连接的表】的每一行是否与连接缓冲区中的每一行匹配。
  • 如果匹配,将形成一个新的扩展行(原始行加上【要连接的表】的列),并会对缓冲区中匹配行的匹配标志进行标记。
  • 检查要连接的表的所有行之后,将扫描缓冲区。
  • 缓冲区中没有被标记的每一行,通过NULL补充进行扩展(【要连接的表】的列设为NULL)。
批量键值访问连接(Batched Key Access Joins,BKA)

批量键值访问连接(Batched Key Access Joins,BKA)和BNL类似,将驱动表(外部表)的行/结果集存入连接缓冲区(join buffer),然后根据buffer中的数据批量地与内表的数据进行匹配,进而减少内层循环的扫描次数。

批量键值访问连接(BKA)时,可以通过索引访问内部表(第二个表)。 BKA可以用于内连接(inner join)、外连接(outer join)、半连接(semijoin )以及嵌套外连接(nested outer joins)。

批量键值访问连接(Batched Key Access Joins,BKA)的流程可以简要地概括为以下几个步骤:

  1. 将驱动表(外部表)的行/结果集存入连接缓冲区(join buffer)。
  2. BKA算法为缓冲区中的所有行构建用于访问要连接表(内表)的键值。
  3. 键值通过Multi-Range Read(MRR)接口提交给数据库引擎。
  4. MRR利用键值在索引中执行查找,并获取由这些键找到的连接表的记录(回表)。
  5. 返回匹配的数据给客户端。

参考: Batched Key Access Joins https://dev.mysql.com/doc/refman/8.0/en/bnl-bka-optimization.html#bka-optimization

Block Nested-Loop Join Algorithm https://dev.mysql.com/doc/refman/8.0/en/nested-loop-joins.html

MRR(Multi-Range Read)优化

MySQl MRR(Multi-Range Read)优化特性基本过程如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 - 进行范围扫描(Range Scans)的时候,MySQL首先只扫描索引获得索引元组(index tuples),并收集相关行的键值(主键Row Id)。
 - 根据键值(Row Id) 对索引元组(index tuples)排序,将排序结果存储到每个会话的内存缓存中(read_rnd_buffer_size 定义大小,默认256K)。
 - 根据键值(primary key)顺序从基表中返回数据(回表)

通过MRR可以减少随机磁盘读的次数,实现对基本表数据的更有序的扫描。

  • 对于InnoDB和MyISAM引擎的表,MRR优化支持索引范围扫描(index range scans )和等价连接(equi-join)等操作。
  • 对于NDB的表,MRR优化支持多范围索引扫描(multiple-range index scans)或通过属性执行等值连接(equi-join by an attribute)操作。
  • MRR优化不支持在虚拟列上创建的辅助索引(secondary indexes created on virtual generated columns)。

参考: 8.2.1.11 Multi-Range Read Optimization https://dev.mysql.com/doc/refman/8.0/en/mrr-optimization.html

通过EXPLAIN查看BKA 的使用

运行SQL时,可以使用EXPLAIN来查看MySQL优化器执行查询的计划,当一个表在查询执行计划中出现 “Using join buffer (Batched Key Access)” 这个提示,且该表的 type 列的值为 ref 或 eq_ref 时,就意味着该表使用了 BKA 算法。 BKA 算法可以有效地优化大表关联查询的性能,减少磁盘 I/O 和内存占用,提高查询速度。

哈希连接算法(hash join algorithm)

MySQL 8.0.18以后的版本中,MySQL可以用哈希连接算法(hash join algorithm)来进行表连接操作。 哈希连接通常要比嵌套循环连接更有效,特别是如果内存可以容纳其中一个表的情况下更加高效。

哈希连接算法(hash join algorithm)将连接操作分为两个阶段:构建哈希表和扫描哈希表。 在构建哈希表阶段,MySQL将连接操作的第一个表插入到哈希表中,其中哈希表的键是连接操作的连接列。 在扫描哈希表阶段,MySQL将连接操作的第二个表的每一行与哈希表中的相应行进行比较,如果它们的连接列匹配,则将它们作为连接操作的结果返回。

哈希连接示例

例如以下查询作为示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SELECT *
FROM t1
JOIN t2 ON t1.column1 = t2.column2;

在执行此查询时,MySQL将使用Hash Join算法来执行连接操作。

例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
--创建测试表
mysql> CREATE TABLE t1 (  id INT PRIMARY KEY,  column1 INT);
Query OK, 0 rows affected (0.84 sec)

mysql> CREATE TABLE t2 (  id INT PRIMARY KEY,  column2 INT);
Query OK, 0 rows affected (0.36 sec)

--插入示例数据
mysql> INSERT INTO t1 VALUES (1, 10), (2, 20), (3, 30), (4, 40), (5, 50);
Query OK, 5 rows affected (0.09 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql> INSERT INTO t2 VALUES (1, 10), (2, 20), (3, 30), (4, 40), (5, 60);
Query OK, 5 rows affected (0.04 sec)
Records: 5  Duplicates: 0  Warnings: 0

--查看执行计划
mysql> explain format=tree
    -> SELECT *
    -> FROM t1
    -> JOIN t2 ON t1.column1 = t2.column2;
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| EXPLAIN                                                                                                                                                                   |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| -> Inner hash join (t2.column2 = t1.column1)  (cost=3.50 rows=5)
    -> Table scan on t2  (cost=0.07 rows=5)
    -> Hash
        -> Table scan on t1  (cost=0.75 rows=5)
 |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

mysql> explain
    -> SELECT *
    -> FROM t1
    -> JOIN t2 ON t1.column1 = t2.column2;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra                                      |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------------------+
|  1 | SIMPLE      | t1    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    5 |   100.00 | NULL                                       |
|  1 | SIMPLE      | t2    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    5 |    20.00 | Using where; Using join buffer (hash join) |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------------------+
2 rows in set, 1 warning (0.00 sec)

mysql>

具体来说,MySQL将按照以下步骤执行Hash Join:

  1. MySQL将从t1中读取所有行,并将它们插入到一个哈希表中,其中哈希表的键是连接列(在此示例中为column1)的值。
  2. MySQL将从t2中读取每一行,并将连接列的值用作哈希表的键来查找哈希表。如果哈希表中存在匹配的行,则将它们作为连接操作的结果返回。
  3. 如果哈希表中不存在匹配的行,则继续扫描t2中的下一行,直到所有行都被扫描完毕。
  4. 在explain执行计划中,通过Extra信息可以看到使用了哈希连接,例:【 Using where; Using join buffer (hash join) 】。

通过使用Hash Join算法,MySQL可以在内存中快速查找匹配的行,从而提高连接操作的性能。但是,如果t1非常大,那么构建哈希表可能会消耗大量的内存,从而导致性能下降。因此,在使用Hash Join算法时,需要根据实际情况评估内存使用情况,并根据需要调整MySQL的配置参数。

参考: 8.2.1.4 Hash Join Optimization https://dev.mysql.com/doc/refman/8.0/en/hash-joins.html

连接算法的选择

SQL查询连接算法的使用和选择,根据MySQL的版本演进也不断发生改变。

  1. MySQL 8.0.18之前的版本,无法使用索引的等值连接(equi-joins )会使用块嵌套循环连接(Block Nested-Loop Join Algorithm)。
  2. MySQL 8.0.18及更高的版本,无法使用索引的等值连接(equi-joins )会使用散列连接(hash join algorithm),当存在一个或多个可用于单表谓词的索引时,也可以使用哈希连接。
  3. MySQL 8.0.18版本,支持使用BNL/NO_BNL和HASH_JOIN/NO_HASH_JOIN提示来控制是否使用哈希连接;也支持通过设置optimizer_switch系统变量的hash_join=on/off参数来控制是否使用哈希连接
  4. MySQL 8.0.19及更高的版本,无法控制SQL查询是否使用哈希连接。
  5. MySQL 8.0.20之前的版本,如果连接的表对没有至少一个等值连接条件,则无法使用哈希连接,并且会使用较慢的块嵌套循环算法。
  6. MySQL 8.0.20及更高的版本,MySQL不再支持块嵌套循环连接,而是使用散列连接来代替所有的块嵌套循环连接的情况。
  7. MySQL 8.0.20及更高版本中,哈希连接也可以用于外连接(包括反连接和半连接)

参考: 【MySQL】控制MySQL优化器行为方法之optimizer_switch系统变量 Hash join in MySQL 8 https://dev.mysql.com/blog-archive/hash-join-in-mysql-8/

例题

例题1:关于哈希连接(Hash Joins)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Choose the best answer. Which condition is true about the use of the hash join algorithm?

A) At least one of the tables in the join must have a hash index. 
B) No index can be used for the join. 
C) The query must access no more than two tables. 
D) The smallest of the tables in the join must fit in memory as set by join_buffer_size.

例题1 解析

参考答案:B

1.无法使用索引的等值连接(equi-joins )会使用散列连接(hash join algorithm)

参考: https://dev.mysql.com/doc/refman/8.0/en/hash-joins.html

Beginning with MySQL 8.0.18, MySQL employs a hash join for any query for which each join has an equi-join condition, and in which there are no indexes that can be applied to any join conditions

2.多表连接也可以使用哈希连接算法。

3.哈希连接算法使用join_buffer_size系统变量控制可以使用的内存量,但不要求连接中最小的表必须适合内存。

例题2:EXPLAIN 执行计划

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Choose two. Which two methods can be used to determine whether a query uses the hash join algorithm?
A) EXPLAIN FORMAT=JSON
B) EXPLAIN FORMAT=TRADITIONAL
C) EXPLAIN FORMAT=TREE
D) EXPLAIN without any formatting argument
E) EXPLAIN ANALYZE

例题2 解析

参考答案:C E

但是根据如下的结果可以看到,EXPLAIN 的任何一个选项都可以看出执行计划是否使用了Hash Join。 如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
A)   "using_join_buffer": "hash join"
B)Using where; Using join buffer (hash join)
C)   Inner hash join
D)  Using where; Using join buffer (hash join)
E)   Inner hash join 

Explain各选项的结果如下:

A) EXPLAIN FORMAT=JSON
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> EXPLAIN FORMAT=JSON
    -> SELECT *
    -> FROM t1
    -> JOIN t2 ON t1.column1 = t2.column2;
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| EXPLAIN                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| {
  "query_block": {
    "select_id": 1,
    "cost_info": {
      "query_cost": "3.50"
    },
    "nested_loop": [
      {
        "table": {
          "table_name": "t1",
          "access_type": "ALL",
          "rows_examined_per_scan": 5,
          "rows_produced_per_join": 5,
          "filtered": "100.00",
          "cost_info": {
            "read_cost": "0.25",
            "eval_cost": "0.50",
            "prefix_cost": "0.75",
            "data_read_per_join": "80"
          },
          "used_columns": [
            "id",
            "column1"
          ]
        }
      },
      {
        "table": {
          "table_name": "t2",
          "access_type": "ALL",
          "rows_examined_per_scan": 5,
          "rows_produced_per_join": 5,
          "filtered": "20.00",
          "using_join_buffer": "hash join",
          "cost_info": {
            "read_cost": "0.25",
            "eval_cost": "0.50",
            "prefix_cost": "3.50",
            "data_read_per_join": "80"
          },
          "used_columns": [
            "id",
            "column2"
          ],
          "attached_condition": "(`testdb`.`t2`.`column2` = `testdb`.`t1`.`column1`)"
        }
      }
    ]
  }
} |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 row in set, 1 warning (0.07 sec)

mysql>

B)EXPLAIN FORMAT=TRADITIONAL
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> EXPLAIN FORMAT=TRADITIONAL
    -> SELECT *
    -> FROM t1
    -> JOIN t2 ON t1.column1 = t2.column2;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra                                      |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------------------+
|  1 | SIMPLE      | t1    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    5 |   100.00 | NULL                                       |
|  1 | SIMPLE      | t2    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    5 |    20.00 | Using where; Using join buffer (hash join) |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------------------+
2 rows in set, 1 warning (0.00 sec)

mysql>
C) EXPLAIN FORMAT=TREE
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> EXPLAIN FORMAT=TREE
    -> SELECT *
    -> FROM t1
    -> JOIN t2 ON t1.column1 = t2.column2;
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| EXPLAIN                                                                                                                                                                   |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| -> Inner hash join (t2.column2 = t1.column1)  (cost=3.50 rows=5)
    -> Table scan on t2  (cost=0.07 rows=5)
    -> Hash
        -> Table scan on t1  (cost=0.75 rows=5)
 |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql>

D) EXPLAIN
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> EXPLAIN
    -> SELECT *
    -> FROM t1
    -> JOIN t2 ON t1.column1 = t2.column2;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra                                      |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------------------+
|  1 | SIMPLE      | t1    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    5 |   100.00 | NULL                                       |
|  1 | SIMPLE      | t2    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    5 |    20.00 | Using where; Using join buffer (hash join) |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------------------+
2 rows in set, 1 warning (0.00 sec)

mysql>
E) EXPLAIN ANALYZE
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> EXPLAIN ANALYZE
    -> SELECT *
    -> FROM t1
    -> JOIN t2 ON t1.column1 = t2.column2;
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| EXPLAIN                                                                                                                                                                                                                                                                                                 |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| -> Inner hash join (t2.column2 = t1.column1)  (cost=3.50 rows=5) (actual time=0.103..0.108 rows=4 loops=1)
    -> Table scan on t2  (cost=0.07 rows=5) (actual time=0.014..0.017 rows=5 loops=1)
    -> Hash
        -> Table scan on t1  (cost=0.75 rows=5) (actual time=0.047..0.053 rows=5 loops=1)
 |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql>
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-06-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 SQL和数据库技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
MySQL实战第三十五讲- join语句怎么优化?
在上一篇文章中,我和你介绍了 join 语句的两种算法,分别是 Index Nested-Loop Join(NLJ) 和 Block Nested-Loop Join(BNL)。
越陌度阡
2022/05/06
3940
MySQL实战第三十五讲- join语句怎么优化?
【MySQL】之join算法详解
在阿里巴巴的java开发手册有这么一条强制规定:超过三个表禁止join,需要join的字段,数据类型保持绝对一致,多表关联查询时,要保证被关联的字段需要有索引。
MySQL数据库技术栈
2020/09/01
7900
【MySQL】之join算法详解
面试之前,MySQL表连接必须过关!——表连接的原理
我们知道,所谓表连接就是把各个表中的记录都取出来进行依次匹配,最后把匹配组合的记录一起发送给客户端。比如下面把t1表和t2表连接起来的过程如下图
砖业洋__
2023/05/06
2.1K0
面试之前,MySQL表连接必须过关!——表连接的原理
深入理解MySQL中的Join算法
在数据库处理中,Join操作是最基本且最重要的操作之一,它能将不同的表连接起来,实现对数据集的更深层次分析。
BookSea
2023/10/12
5770
Mysql几种join连接算法
相信有开发或DBA小伙伴,对于mysql处理多表关联方式或者说性能方面一直不太满意,对于开发提交的join查询,一般都是比较抗拒的,从而建议将join进行拆分,避免join带来的性能问题,同时也避免了程序与数据库带来网络开销的问题
黎明大大
2020/09/17
2.7K0
Mysql几种join连接算法
MySQL8.0 优化器介绍(二)
join在MySQL 是一个如此重要的章节,毫不夸张的说,everything is a join。
GreatSQL社区
2023/08/10
2500
MySQL8.0 优化器介绍(二)
性能优化之Block Nested-Loop Join(BNL)
相信许多开发/DBA在使用MySQL的过程中,对于MySQL处理多表关联的方式或者说性能一直不太满意。对于开发提交的含有join的查询,一般比较抗拒,从而建议将join拆分,避免join可能带来的性能问题,同时也增加了程序和DB的网络交互。
用户1278550
2018/08/09
5.6K0
35 | join语句优化
一般来说,使用join语句,会用到两种算法,分别是Index Nested-Loop Join(NLJ) 和 Block Nested-Loop Join(BNL)。
HaC
2020/12/30
8540
35 | join语句优化
MySQL 8.0 新特性:引人注目的哈希连接(Hash Join)
blog.csdn.net/horses/article/details/102690076
肉眼品世界
2020/11/11
7490
MySQL 8.0 新特性:引人注目的哈希连接(Hash Join)
MySQL - Join关联查询优化 --- NLJ及BNL 算法初探
两个表 t1 和 t2 , 一样的,包括索引信息 a 字段有索引 b字段没有索引。
小小工匠
2021/08/17
1.6K0
细品mysql之Join 语句的执行过程
今天优化了一个,join关联查的语句,需要优化join的语句,那我们肯定得了解他的一个执行过程。正所谓知己知彼,百战百胜!!
袁新栋-jeff.yuan
2020/09/24
1.1K0
细品mysql之Join 语句的执行过程
MySQL Hash Join实现分析
提示:公众号展示代码会自动折行,建议横屏阅读 「前言」 连接操作是一种数据库中最基本的操作,连接算法的执行效率直接影响到整个数据库的效率、吞吐和资源。通常商业数据库系统一般有三种主流的连接实现:Nested Loop Join、Hash Join和Sort Merge Join。本文概述目前主流的Hash Join实现方式,以及分析MySQL中Hash Join的实现方式。 MySQL 8.0.18 版本增加了对Hash Join算法的支持,在此之前,连接算法仅支持嵌套循环连接 Nested Loop J
腾讯数据库技术
2021/12/30
2.5K1
技术分享 | 咬文嚼字之驱动表 & outer表
爱可生 DBA 团队成员,擅长故障分析、性能优化,个人博客:https://www.jianshu.com/u/a95ec11f67a8,欢迎讨论。
爱可生开源社区
2021/11/30
1.2K0
join查询可以⽆限叠加吗?MySQL对join查询有什么限制吗?
假设有一个复杂的业务系统,涉及到用户表(users)、订单表(orders)、商品表(products)、物流表(logistics)和支付表(payments)。如果编写如下的 JOIN 查询:
威哥爱编程
2025/02/24
1670
Nested-Loop Join Algorithms
高爽
2017/12/28
1.2K0
MySQL连接的原理⭐️4种优化连接的手段性能提升240%🚀
上两篇文章我们说到MySQL优化回表的三种方式:索引条件下推ICP、多范围读取MRR与覆盖索引
菜菜的后端私房菜
2024/06/14
3761
要面试了,你还没有掌握MySQL join的原理?
join 是 MySQL 用来进行联表操作的,用来匹配两个表的数据,筛选并合并出符合我们要求的结果集。
hugo_lei
2021/08/16
5940
要面试了,你还没有掌握MySQL join的原理?
MySQL通过索引优化-这里可能有你不知道的索引优化细节(二)
用执行计划分别测试一下union all、in和or,发现union all分两步执行,而in和or只用了一步,效率高一点。
行百里er
2020/12/02
8980
MySQL通过索引优化-这里可能有你不知道的索引优化细节(二)
线上mysql出现Block Nested-Loop Join问题
最近线上遇到一个问题,后台一个查询把服务给整挂了,然后找了dba看了下sql慢查询,我们explain一下结果。
公众号-利志分享
2022/04/25
2.3K0
线上mysql出现Block Nested-Loop Join问题
MySQL8.0发布,你熟悉又陌生的Hash Join?
昨天下午在查资料的时候,无意间点到了MySQL的doc。发现MySQL发布了一个新版本。
王知无-import_bigdata
2020/02/10
8110
相关推荐
MySQL实战第三十五讲- join语句怎么优化?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档