深度剖析 SQL JOIN:底层机制与性能优化策略

前言-join是什么

join是用于,将多个表中的数据依据一定的关联条件进行组合。往往我们用于做条件的等值关联。(不等值的结果集往往非常大)。但不同join sql之间的性能天差地别,让我们看看深入理解join的底层机制,合理的使用join语法。

join的方式

可以想到,join的工作可以被拆解成两步,

  1. 字段匹配:根据条件匹配,不同表的数据
  2. 表合并:将匹配的数据,以及不同表的数据项合并成一张虚拟表

而优化join的关键,就在于理解字段匹配的机制。

字段匹配逻辑

而多张表的匹配,可以想到,可拆解成,先用一张表,作为待匹配集,也被称为驱动表。然后再循环匹配剩下n-1张表。剩下n-1张表,也称为被驱动表

Nested Loop Join

细分类型

Nested Loop Join(嵌套循环连接)MySQL 5.6 支持,可细分为以下几种类型:

  • Simple Nested Loop Join:最为基础的嵌套循环,外层表的每一行都会和内层表的所有行进行比较。
  • Index Nested Loop Join:若内层表存在索引,MySQL 会利用该索引来加速匹配过程,从而减少内层表的扫描行数。
  • Block Nested Loop Join:当没有合适的索引时,MySQL 会使用该算法。它会把外层表的一部分数据加载到缓存中,然后和内层表进行匹配,以此来减少内层表的扫描次数。

Index Nested Loop Join

表关联是使用索引进行匹配的。

Hash Join

在 MySQL 5.6 里,Hash Join 默认是不支持的。Hash Join 是一种更为高效的连接算法,它先对其中一个表构建哈希表,接着再用另一个表去匹配该哈希表,从而减少比较次数。从 MySQL 5.7 开始,InnoDB 存储引擎才支持 Hash Join。

例子

sql 复制代码
SELECT ... FROM R LEFT JOIN S ON R.x = S.x WEHRE ... -R是驱动表

SELECT ... FROM R RIGHT JOIN S ON R.x = S.x WEHRE ... -S是驱动表

SELECT ... FROM R INNER JOIN S ON R.x = S.x WEHRE ... -DB会根据算法,选择驱动表

DB选择驱动表的原则

谁要查询的数据少,谁就是驱动表

Hash Join

hash join用于连接两张表之间,没有索引的情况。

如果强行创建索引,会有问题:

  1. 如果有些列是低选择度的索引,那么创建索引在导入数据时要对数据排序,影响导入性能;
  2. 二级索引会有回表问题,若筛选的数据量比较大,则直接全表扫描会更快。

具体过程

  1. 扫描驱动表,将其中的key value hash起来
  2. 扫描第二张表,根据hash表匹配

总结

  1. JOIN 概述JOIN 用于依据关联条件组合多表数据,常采用等值关联
  2. JOIN 工作步骤 :可拆分为字段匹配表合并两步,优化关键在于理解字段匹配机制。
  3. 字段匹配逻辑 :多表匹配时,选择一张表作为驱动表,其余为被驱动表,依次循环匹配。
  4. Nested Loop Join:MySQL 5.6 支持,分为 Simple、Index 和 Block Nested Loop Join 三种。Index 类型借助内层表索引加速匹配;Block 类型在无合适索引时,将外层表部分数据加载到缓存匹配,减少扫描次数。
  5. Hash Join:MySQL 5.7 起 InnoDB 存储引擎支持。适用于表间无索引的情况,强行创建索引可能影响导入性能或因回表问题降低效率。其过程是先扫描驱动表构建哈希表,再用另一张表匹配。
  6. 驱动表选择原则:数据库通常选择查询数据少的表作为驱动表。
  7. 使用建议 :业务中使用 JOIN 时,要确保驱动表和被驱动表选择正确,并创建预期内的索引。
相关推荐
一 乐13 分钟前
绿色农产品销售|基于springboot + vue绿色农产品销售系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·后端·宠物
3***688424 分钟前
Spring Boot中使用Server-Sent Events (SSE) 实现实时数据推送教程
java·spring boot·后端
C***u17628 分钟前
Spring Boot问题总结
java·spring boot·后端
上进小菜猪28 分钟前
基于 YOLOv8 的人体与行人检测智能识别实战 [目标检测完整源码]
后端
Elieal42 分钟前
5 种方式快速创建 SpringBoot 项目
java·spring boot·后端
c***69301 小时前
Spring Boot实时推送技术详解:三个经典案例
spring boot·后端·状态模式
Mr -老鬼1 小时前
Rust适合干什么?为什么需要Rust?
开发语言·后端·rust
12344522 小时前
Agent入门实战-一个题目生成Agent
人工智能·后端
IT_陈寒2 小时前
Java性能调优实战:5个被低估却提升30%效率的JVM参数
前端·人工智能·后端
快手技术2 小时前
AAAI 2026|全面发力!快手斩获 3 篇 Oral,12 篇论文入选!
前端·后端·算法