当前位置: 首页 > news >正文

Mysql杂志(三十一)——Join连接算法与子查询、排序优化

Join连接算法

我们之间也说过join其实就是一次又一次的循环对比,A连接B,那么就是先找到A表所以复合条件的行数据,然后一条一条的循环扫描满足条件的B数据,最后输出结果。先看看这几个算法的对比表格:

算法类型

引入版本

核心机制

最佳场景

触发条件

Nested Loop Join

全版本

双重循环匹配

中小表关联

默认算法

Block Nested Loop

全版本

缓冲块优化

无索引连接

join_buffer_size足够

Hash Join

8.0+

哈希表加速

大表等值连接

无合适索引+等值条件

Batched Key Access

5.6+

批量键访问

二级索引回表

mrr=on

1. 嵌套循环连接 (Nested Loop Join)

这个其实就是开头说的那种,也是mysql中最简单而且是默认的算法,其实这个算法也分两种一个是Simple Nested Loop Join,一个是Index Nested Loop Join,前者就是不使用索引的简单循环算法,假设A有100条,B也有100条,那么总共的成本就是100*100=1w,所以查询的成本其实是非常高的,而第二种就是使用索引,通过聚餐索引或者二级索引直接定位满足条件的行,性能会高很多。

2. 块嵌套循环连接 (Block Nested Loop)

这个其实就是把被驱动表的数据加载到内存块中(没有索引的情况下),本来A的数据扫描B需要加载到内存中,而且是扫描一次就加载一次很浪费资源,而这个就是直接把B表的一部分加载到内存中,然后进行循环匹配,不合适的就加载下一部分内存,下次循环还是会使用这个内存块,不会重复加载,但是这个是受到缓存块大小的限制,而且mysql8.2被Hash join替代了这个算法。

3. 哈希连接 (Hash Join)

这个就是为了替代Block Nested Loop而产生的算法,这个的限制就是必须是等值查询,而且在没有索引的情况下,不支持 LIKE, >, <等范围条件,而且性能不足的情况下性能会显著下降,因为哈希表的特性就是找对应的桶,或者叫数据指针,这个就是为被驱动表建立哈希表,然后循环查找的时候就查询这个哈希表。这个是对比表格:

对比维度

Hash Join

Block Nested Loop (BNL)​

算法类型

哈希表查找

块嵌套循环

引入版本

MySQL 8.0+

全版本支持

连接条件

仅支持等值连接(=)

支持所有连接条件

内存使用

高(需构建哈希表)

中(join_buffer缓存)

执行阶段

构建阶段+探测阶段

单阶段块扫描

最佳场景

大表等值连接

中小表无索引连接

I/O特点

随机I/O为主

顺序I/O为主

4. 批量键访问 (Batched Key Access)

批量键访问 (Batched Key Access, BKA) 是 MySQL 针对二级索引回表查询的优化技术,通过将随机 I/O 转换为顺序 I/O 提升性能。这个是开启的条件:

条件类型

具体要求

检查方法

系统配置

optimizer_switch='batched_key_access=on'

SHOW VARIABLES

查询特征

使用二级索引且需要回表

EXPLAIN显示 Using index condition

版本要求

MySQL 5.6+

SELECT VERSION()

这个是优点:

优点

影响程度

产生效果

减少随机I/O

★★★★★

大幅降低延迟

提高缓存命中

★★★★

减少物理读

批量处理

★★★

降低系统调用

预读优化

★★

利用磁盘特性

这个是缺点:

缺点

影响程度

缓解方案

内存消耗

★★★

调整join_buffer_size

额外排序

★★

确保mrr_cost_based=off

冷数据效果差

★★

预热缓存

版本限制

升级到5.6+

简单来说这个其实是搭配Nested Loop Join使用的,本来使用二级索引需要回表的,而且每找到一次就要回表一次,使用这个后会把需要回表的索引记录到内存缓存中,然后一次性回表,把大量的随机IO变成了一次的顺序IO性能提升还是很明显的,而且Mysql默认是开启的。

其实总结起来就是一句话,小表驱动大表,小结果集驱动大结果集,因为小结果驱动代表的就是减少循环的次数。

子查询优化

子查询大家应该都不陌生,子查询是mysql4的时候引入的一个功能,目的就是为了帮助我们完成更加复杂的业务场景,但是子查询其实本质上来说性能并不好,因为子查询会生成一个临时表,我们都知道无法给临时表添加索引(当然主包说的是隐式的临时表,我们显示声明的还是可以加索引的),那么如果一个表的数据集特别大,然后子查询又是select* 这种全字段,然后我们的主表再使用这个子查询的某个字段查询的时候,性能就是非常糟糕的,一个是没有索引,一个就是数据量特别大,而且在生成和最后删除临时表的时候,也是非常消耗系统资源的。所以我们需要对一些需要使用子查询的场景进行优化,从而提高sql的性能。

1. 子查询转为JOIN(最常用)

这个其实很好理解,因为一个是可以使用被驱动表的索引,一个是循环对比被驱动表的行数据,最后形成一个结果集,并不会产生一个中间的临时表,也就不存在大量的系统资源浪费了。

2.派生表条件下推(5.7+)以及减少列数量

这个其实也很好理解,把过滤条件下推到子查询中,不要在外层查询中再过滤,因为这样会降低临时表产生的数据集,从而导致性能提高,另外不要使用select * 只返回需要的字段,这样性能也会提高。

-- 低效写法
SELECT * FROM (SELECT * FROM orders WHERE status = 'completed'
) AS t WHERE t.amount > 1000;-- 优化写法(条件下推)
SELECT * FROM (SELECT * FROM orders WHERE status = 'completed' AND amount > 1000
) AS t;

3.EXISTS重写

这个其实在mysql中会被优化成半连接,也就是只保留true的驱动表行数据,为什么性能会提高其实是上面说过,转Join一样。

排序优化

1.使用limit

其实我们在进行排序的时候,就算有这个字段的索引,也可以会失效,因为二级索引是需要回表的,而且我们也知道Mysql优化器是以成本最低为前提的,假如使用索引比不使用索引成本更高,肯定就不会使用索引,就是说多个列的组合索引全部命中的情况下,所以使用limit进行分页的话,这样就会降低回表的数量集,所以使用索引的可能性会高。

2.索引顺序

这个就很好理解了,我们知道索引是有升序和降序的,默认是升序的索引,假如我们对一个字段进行降序排序,那么肯定就不会使用到索引的,我们需要更加业务情况添加降序索引。

3.文件排序算法——单路排序、双路排序

其实我们大部分的场景使用的都是文件排序,也就是把数据加载到内存,然后再进行排序,之前我们说降序排序的时候就知道了,文件排序是很消耗系统资源的,但是这个也是没办法的,因为我们不可能什么情况下都加索引对不对。所以我们有需要了解一下什么是单路排序什么是双路排序。

单路排序:也就是一次性把满足条件的数据全部加载到内存然后进行排序,缺点就是消耗内存(sort_buffer_size),优点就是比双路快,5.7以上版本默认这个算法。

双路排序:就是先把排序列和主键加载到内存排序,然后再批量回表获取数据,缺点就是2次IO会慢,但是消耗的内存会小很多。

总结

本篇主要讲的就是Join的连接算法以及子查询和排序优化的一些内容。

http://www.dtcms.com/a/469798.html

相关文章:

  • HashMap - 底层原理
  • Python第二次作业
  • Vspy使用教程
  • 通用网站模板网站备案要幕布照
  • 网站三要素关键词 描述怎么做青海项目信息网官网
  • JavaScript学习笔记(二十八):JavaScript性能优化全攻略
  • mooc自动互评脚本笔记---2025年10月11日
  • 什么是语言模型
  • 免费网站正能量不用下载网站程序是什么?
  • 海外住宅IP的分类方式
  • wpf之ToggleButton控件
  • 【传奇开心果系列】基于Flet框架实现的文件选择文件保存和目录选择的样例自定义模板特色和实现原理深度解析
  • 做网站什么数据库用的多低价建站在哪里买
  • 从零搭建 React Native 到项目运行全记录(0.73.6 稳定版)
  • HTML DOM 对象
  • 红日靶场(四)——个人笔记
  • b树,b+树,红黑树
  • win7 iis网站无法显示上海网站设计公司有哪些
  • 马来西亚代表团到访愿景娱乐 共探TikTok直播电商增长新路径
  • 唯识主义:哲学爱智慧本质的当代回归
  • 网站开发公司照片网站建设开发协议
  • 小网站模板网页传奇推荐
  • 支持400+格式!FileOptimizer文件一键压缩
  • 【Unity笔记】Unity Lighting Settings 全解析:一文读懂烘焙光照的每个参数(VR项目Lighting优化)
  • 全链路智能运维中的业务负载预测与弹性伸缩机制
  • 健康管理实训室建设方案:标准化构建与质量保障
  • 甘肃建设局网站wordpress获取文章来源
  • 超简洁网站网络软文营销
  • XXE 注入漏洞全解析:从原理到实战
  • edu div2 183个人笔记(目前只补到D,后续可能会更新)