SQL性能优化指南:如何优化MySQL多表join场景

news2024/12/24 19:21:07

目录

多表join问题SQL

这里解释下 Using join buffer (Block Nested Loop):

对性能产生的影响:

三种join算法介绍

join操作主要使用以下几种算法:

(1)Nested Loop Join

(2)Block Nested Loop Join

(3)Index Nested Loop Join

问题定位

DBdoctor SQL审核-识别多表Join问题

总结


多表join问题SQL

对于某个复杂业务场景,通常需要根据多个过滤条件才能拿到两个表中的信息。例如,某开发同事费了半天劲写了一个多表join的SQL实现了功能,但上线后却发现对应接口响应特别慢,通过一步步排查后才定位到问题SQL,SQL如下:


select cell.*, res.pod_name from dbfree.dbins_cell cell right join dbfree.dbins_resource res on 
cell.ip = res.pod_ip where cell.ip in ('10.174.156.14', '10.174.187.144', '10.174.67.11') and
res.path in ('/dev/sdb6', '/dev/sdb5') order by res.namespace;

看下该问题SQL的执行计划:

图片

执行计划中可以看到两个表的type都是ALL,且cell表的Extra中出现 Using join buffer (Block Nested Loop),代表两个表发生了全表扫描,且使用了join buffer。

这里解释下 Using join buffer (Block Nested Loop):

  • Using join buffer:表示 MySQL 在执行JOIN时使用了连接缓冲区。这意味着外层表的部分行被加载到内存中,以便与内层表进行匹配。

  • (Block Nested Loop):指的是 MySQL 使用了块嵌套循环算法,而不是简单的嵌套循环。这种方法优化了JOIN操作,尤其是在内层表没有索引时,能够提高连接的性能。

对性能产生的影响:

  • 内存使用: 使用连接缓冲区意味着 MySQL 会消耗更多内存,因此可以处理更大块的数据,从而减少 I/O 操作并提高性能。

  • 缺乏索引: 这个提示通常表明内层表缺乏合适的索引,导致 MySQL 需要通过全表扫描的方式来处理JOIN操作。虽然 Block Nested Loop比简单的嵌套循环更高效,但相较于使用索引,仍然可能比较慢。

三种join算法介绍

join操作是一种将两个或多个表的行结合起来的方法,本质就是把各个表中的记录都取出来依次匹配的组合加入结果集并返回给用户。

例如SQL:

select * from employee e join department d on e.id = d.employee_id

join操作主要使用以下几种算法:

(1)Nested Loop Join

这是最基本的连接算法,也被称为嵌套循环连接。对于第一个表中的每一行,它会扫描第二个表中的所有行来寻找匹配的行。这种方法的效率通常较低,特别是当表的大小增加时,因为它需要进行大量的磁盘I/O操作。

相当于两个嵌套for循环:


for(employee表行 eRow : employee表){
    for(department表的行 dRow : department表){
        if(eRow.id = dRow.emp_id){
            return eRow;
        }
    }
}

图片

例如 employee 表有2行,department表有3行,Nested Loop Join 算法的开销如下:

  • 每一次循环,employee表扫描1次,department表比较3次

  • 共有2次循环,比较 2 * 3 = 6次

MySQL不会简单的使用Nested Loop Join,而是利用buffer,即Block Nested Loop Join。

(2)Block Nested Loop Join

这是一种改进的嵌套循环连接算法,核心思路是减少内层表的扫表次数,它使用了一个叫做连接缓冲区(join buffer)的内存结构来减少磁盘I/O操作。将第一个表按照join_buffer_size的大小进行分块(Block),将每个块作为一批数据放入缓存(而不是单独的一行),它会扫描第二个表中的所有行来寻找匹配的行。这种方法的效率通常比嵌套循环连接要高。

图片

Block Nested Loop Join 算法有以下特点:

  • 当执行计划中的type为ALL、INDEX或RANGE时,可以使用buffer。

  • 可以修改参数optimizer_switch中的block_nested_loop,设置是否开启该算法,默认为on。

    图片

  • 如果buffer大小配置的足够大,可以将employee表的全部数据放入,则department表仅需要扫表1次。join_buffer_size默认大小为256K。

  • 增大buffer_size是一种优化思路,同理,去除不必要的查询字段,减少需要放入buffer中的数据也是一个方向。

  • 在MySQL 8.0.18版本及以后,使用 hash join代替Block Nested Loop Join,基本思想是将驱动表的数据加载到内存(数据大小超过join_buffer_size时加载到磁盘,性能会变差),并建立hash表,这样只需要遍历一次驱动表,然后再去通过hash表寻找匹配的行。

(3)Index Nested Loop Join

这是一种改进的嵌套循环连接算法,核心思路同样是减少内层表的匹配次数,需要关联字段在被驱动表中建立索引。对于第一个表中的每一行,它使用索引来查找第二个表中的匹配行,而不是扫描整个表。这种方法的效率通常比嵌套循环连接要高,但前提是必须有适当的索引。

图片

有了合适的索引后,Index Nested-Loop Join算法可以将匹配次数由 外层表行数 * 内层表行数 减少为 外层表行数 * 内层表索引的高度。

问题定位

综上所述,编写多表join的SQL时,通常的连接优化方向如下:

图片

再回过头来看文章最开头的问题SQL


select cell.*, res.pod_name from dbfree.dbins_cell cell right join dbfree.dbins_resource res on 
cell.ip = res.pod_ip where cell.ip in ('10.174.156.14', '10.174.187.144', '10.174.67.11') and
res.path in ('/dev/sdb6', '/dev/sdb5') order by res.namespace;

可以从以下几个角度排查问题:

  1. 关联字段是否有索引

  2. 若关联字段有索引,索引有没有失效

  3. 小表驱动大表

  4. 不要使用 * 作为查询列,只返回需要的列

经排查发现,被驱动表cell的关联字段ip不存在索引,DBA认为找到问题了,可是给字段cell.ip加上索引后,再次查看执行计划。

图片

咦,驱动表怎么换了?执行计划中第一行为驱动表,第二行为被驱动表。cost优化器认为经过where cell.ip in 条件过滤后的cell表数据更少,更适合作为驱动表。DBA继续给res.pod_ip加索引,再次查看执行计划。

图片

执行计划中type没有all了,但是第二行res表的ref怎么是func?连接条件为等值查询,字段cell.ip和res.pod_ip类型均为varchar,怎么还会有函数操作?

  • func表示索引查找涉及函数或表达式:当你在 JOIN 或 WHERE 子句中使用了函数或表达式(比如字符串函数、日期函数、数学运算等),MySQL 可能无法直接使用索引进行等值匹配,而是会调用某个函数来计算结果。这会导致 MySQL 在执行计划中显示 ref 为 func

DBA没招了,那就用DBdoctor吧,其免费的SQL审核功能可以很方便的发现多表Join的相关问题。

DBdoctor SQL审核-识别多表Join问题

在DBdoctor 3.2.3 版本中,完善了SQL审核的全生命周期覆盖,自动闭环审核出的问题SQL,新增了SQL审核静态规则 300+,其中就有部分和多表join相关的规则。

将问题SQL放入SQL窗口,点击审核。

图片

审核任务报表中出现多表关联,关联字段charset不同,导致索引失效

图片

点击查看审核详情,展示了每条命中规则的解释和建议;除命中规则外,DBdoctor通过自研Cost优化器给出了各个索引的性能分析结果,并基于此推荐了最优索引。

图片

可以看到

  • 问题分析部分,有一条严重问题:多表关联,关联字段charset不同,导致索引失效,关联条件左侧字段ip 的charset为 latin1,右侧字段pod_ip 的charset为 utf8mb4。

那这条sql的问题就非常清楚了,关联字段的charset不一样

开发同学修改cell表的字符集,再次查看执行计划:

图片

可以看到被驱动表type为ref,ref列中使用了索引dbfree.cell.ip,至此问题解决。

但是驱动表中的extra信息出现了Using filesort、Using temporary,详细介绍可参考《一条SQL使用order by,引发IO问题》《MySQL Using temporary案例详解及优化方法》

总结

编写多表join的SQL时,需要注意关联字段是否使用索引、小表驱动大表、适当调整join buffer大小等。DBdoctor 3.2.3版本提供了强大的SQL审核工具,它可以帮助开发者在代码部署前识别并解决潜在的SQL问题。现在,小伙伴们可以免费体验这项功能,提升你的数据库性能和稳定性。立即下载DBdoctor,让你的SQL编写更加高效和安全!

*****************************************************************************

点击了解更多:DBdoctor-1分钟定位数据库性能问题DBdoctor是一款企业级数据库监控、巡检、性能诊断、SQL审核与优化平台,利用eBPF透视数据库内核,可一分钟定位数据库性能问题,实现根因诊断,并给出优化建议。icon-default.png?t=O83Ahttps://www.dbdoctor.cn/?utm=4cf70f49547b4b45864ac76d1da334bf

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2211506.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

生信服务器配置:优化生物信息学数据处理的最佳实践

介绍 在生物信息学研究中,处理和分析大规模数据集(如基因组、转录组和蛋白质组数据)需要强大的计算资源和精确的服务器配置。生信服务器配置的优化可以显著提高数据处理的效率和结果的准确性。本文将探讨生信服务器配置的关键要素&#xff0…

【LeetCode热题100】分治-快排

本篇博客记录分治快排的4道题目&#xff1a;颜色分类、排序数组、数组中的第K个最大元素、数组中最小的N个元素&#xff08;库存管理&#xff09;。 class Solution { public:void sortColors(vector<int>& nums) {int n nums.size();int left -1,right n;for(int…

【实战项目】——Boost搜索引擎(五万字)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、项目的相关背景 1.1、什么是Boost库&#xff1f; 1.2、什么是搜索引擎&#xff1f; 1.3、为什么要做Boost库搜索引擎&#xff1f; 二、搜索引擎的宏观原…

VirtualBOX虚拟机提高速度,鼠标卡顿解决——未来之窗数据恢复

一、刚安装完操作系统&#xff0c;鼠标操作不灵敏 需要安装系统增强 二、系统增强作用 1.鼠标丝滑 2.文件共享 3.可以共享剪贴板 三、安装步骤-设备-安装增强 四、安装步骤-设备-选择光驱 五、安装增强软件然后重启 六、阿雪技术观 拥抱开源与共享&#xff0c;见证科技进…

【算法】动态规划:从斐波那契数列到背包问题

【算法】动态规划&#xff1a;从斐波那契数列到背包问题 文章目录 【算法】动态规划&#xff1a;从斐波那契数列到背包问题1.斐波那契数列2.爬楼梯3.零钱转换Python代码 4.零钱兑换 II5.组合数dp和排列数dp6.为什么动态规划的核心思想计算组合数的正确方法代码实现 为什么先遍历…

【C++打怪之路Lv8】-- string类

&#x1f308; 个人主页&#xff1a;白子寰 &#x1f525; 分类专栏&#xff1a;重生之我在学Linux&#xff0c;C打怪之路&#xff0c;python从入门到精通&#xff0c;数据结构&#xff0c;C语言&#xff0c;C语言题集&#x1f448; 希望得到您的订阅和支持~ &#x1f4a1; 坚持…

智能汽车智能网联

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 屏蔽力是信息过载时代一个人的特殊竞争力&#xff0c;任何消耗你的人和事&#xff0c;多看一眼都是你的不…

深入理解线性表--顺序表

目录 顺序表- Seqlist -> sequence 顺序 list 表 顺序表的概念 问题与解答 顺序表的分类 静态顺序表 动态顺序表 问题与解答(递进式) 动态顺序表的实现 尾插 头插 尾删 头删 指定位置插入 指定位置删除 销毁 总结 前言&#xff1a;线性表是具有相同特性的一类数据结构…

【exceljs】纯前端如何实现Excel导出下载和上传解析?

前段时间写过一篇类似的文章&#xff0c;介绍了sheetjs。最近发现了一个更好用的库ExcelJS&#xff0c;它支持高级的样式自定义&#xff0c;并且使用起来也不复杂。实际上sheetjs也支持高级自定义样式&#xff0c;不过需要使用付费版。 下面对比了Exceljs和Sheetjs&#xff1a…

Linux的习题+一道回溯类型的算法题

Linux的习题 Linux环境与版本 1.linux 2.6.* 内核默认支持的文件系统有哪些&#xff1f;[多选] A.ext3 B.ext2 C.ext4 D.xfs E.ufs 正确答案&#xff1a;ABCD A 全称Linux extended file system, extfs,即Linux扩展文件系统&#xff0c;ext2为第二代 D XFS一种高性能的日…

使用频率最高的 opencv 基础绘图操作 - python 实现

以下是 opencv-python 基本操作绘制示例&#xff0c;绘制&#xff1a; 1&#xff09;圆&#xff0c;2&#xff09;矩形&#xff0c;3&#xff09;线段&#xff0c;4&#xff09;文本。 安装 opencv-python pip install opencv-python 在图上绘制圆的操作&#xff0c;示例如…

HCIP-HarmonyOS Application Developer 习题(五)

1、以下哪种原子化布局能力属于自适应变化能力? A. 拉伸 B.占比 C. 隐藏 D.拆行 答案&#xff1a;A 分析&#xff1a;划分为“自适应变化能力”和“自适应布局能力”两类。 其中&#xff0c;自适应变化能力包含了缩放能力和拉伸能力&#xff0c;自适应布局能力包含了隐藏、折…

『Mysql进阶』Mysql explain详解(五)

目录 Explain 介绍 Explain分析示例 explain中的列 1. id 列 2. select_type 列 3. table 列 4. partitions 列 5. type 列 6. possible_keys 列 7. key 列 8. key_len 列 9. ref 列 10. rows 列 11. filtered 列 12. Extra 列 Explain 介绍 EXPLAIN 语句提供有…

Spring学习——SpringAOP

0. IOC思想(DI)1. 关键注解Repositorypublic class DeptDaoImpl1 implements DeptDao{}RepositoryPrimarypublic class DeptDaoImpl2 implements DeptDao{}Servicepublic class DeptServiceImpl implements DeptService{AutowiredQulifier("deptDaoImpl2")private De…

UE5学习笔记24-添加武器弹药

一、给角色的武器添加弹药 1.创建界面&#xff0c;根据笔记23的界面中添加 2.绑定界面控件 UPROPERTY(meta (Bindwidget))UTextBlock* WeaponAmmoAmount;UPROPERTY(meta (Bindwidget))UTextBlock* CarriedAmmoAmount; 3.添加武器类型枚举 3.1创建武器类型枚举头文件 3.2创建文…

C++容器:map

1.铺垫 1.1map和unorder_map&#xff0c;两者的实现思想不同&#xff0c;但是用法是相同的&#xff1b;map的思想是平衡二叉树&#xff1b;unorder_map的思想是哈希&#xff1b; 1.2在现实及做题中&#xff0c;百分之99&#xff0c;都在使用unorder_map&#xff0c;接下来的讲…

2024 第一次周赛

A: 题目大意 骑士每连续 i 天每天会得到 i 个金币&#xff0c;&#xff08;i 1&#xff0c; 2&#xff0c; 3 &#xff0c; …&#xff09;,那么展开看每一天可以得到的金币数&#xff1a;1 2 2 3 3 3 4 4 4 5 5 5 5 5 … 可以发现就是1个1 &#xff0c;2个2, 3个3…,那么我…

P20机型HW睡眠省电-调研

摘要 AI睡眠场景识别 不激进的智能管控 睡眠省电 UI 以前有单独的睡眠开关选项&#xff0c;现在没有了&#xff0c;但是智能充电模式是使用AI睡眠模式 睡眠识别 华为专利上提到的论文《BTP-A Bedtime Predicting Algorithm》 各种事件状态&#xff08;亮灭屏、alarm、主动…

《数字信号处理》学习08-围线积分法(留数法)计算z 逆变换

目录 一&#xff0c;z逆变换相关概念 二&#xff0c;留数定理相关概念 三&#xff0c;习题 一&#xff0c;z逆变换相关概念 接下来开始学习z变换的反变换-z逆变换&#xff08;z反变化&#xff09;。 由象函数 求它的原序列 的过程就称为 逆变换。即 。 求z逆变换…

RTR-Chapter8

第八章 光与颜色 光量辐射度量学光度学色度学使用RGB颜色进行渲染 从场景到屏幕HDR显示编码色调映射色调再现变换曝光 颜色分级 光量 辐射度量学 辐射度量学&#xff08;radiometry&#xff09;研究的是对电磁辐射&#xff08;electromagnetic radiation&#xff09;的测量&am…