MYSQL慢SQL优化进阶--多表联查并排序

12 篇文章 0 订阅
9 篇文章 0 订阅

2022.11.01 杭州.mysql性能优化

背景

Mysql改造之后,测试人员进行测试,发现有部分查询sql语句耗时过长,造成查询或者报表导出长时间无反应,如1h,8s之类的,也十分占用数据库资源,故进行慢sql性能调优。

原慢sql

我帮助分析其中8s的一个,原语句为:
涉及约为13张表,就是普通的where on 隐式链接条件查询,除了语法的inner join 外存在以下难点
1.dev_dept字段匹配获取十分困难,两张表联查数据结果为14.8w行
2.行内视图排序十分困难,总共18.5W行数据,排序耗时过长

在这里插入图片描述
同事初步优化后,时长反而增加到11s,sql为:
我刚好闲下来,也找组长要了mysql性能调优的活,所以同事让我帮忙分析为何优化后时长反而提升。
我一层层执行,开始排查原因,直到dev_dep和排序t处,语句都很快1s不到,但一旦加上排序,时间飙升到6s+,再加上dev_dept时间飙升到11s+
在这里插入图片描述

优化历程

第一次优化
我在原语句上,把T6层去掉,把dev_dept移到T3,也是dev_dept_c所在的地方,把product_name也移到T2的resource_id处;
这样就少了一层数据的处理,数据总共18W+,每一层耗时都很大的,再次执行,时间降到8s,与未优化时耗时相同。

第N次尝试优化
多个方法尝试无果后,我发现一些表只用到一个字段,也只与其他表联查一个字段,比如app_def和dev_org、plan_app_rel和plan_def、api_res_extend和api_res等,我尝试先将这些表分别处理好再联查;
语句执行时,我注意到数据量都不同,还以为哪写错了或是没救了,最后排查到 dev_dept和product_name,我当时用的是inner join,于是把那些为空的数据都筛出去了,改为left join后就正常了,但到最后速度还是8s左右

倒数第二次尝试
至此我想着最后尝试一次,可以将这几个表分离开来,最后只是两个或者三个大表来inner join,这样每层的数据量没有那么多,就开始了尝试
,首先判断好每张表的数据量,dev_dept字段两张表联查数据结果为14.8w行,plan_res的数据量为46w行,其他的就都还好。
我决定最先开始处理plan_res,以及去单字段的表都先处理好作为一个大表,将plan_res相关及其相关的表都联查完了,这就作为第一张大表T5;
将剩余的表api_res_extends、api_res以及dev_dept和product_name表进行处理,得出第二张表T6;
两张表单独查询都很快,1s不到,合起来最终查询,只要不排序,时间都在1s左右,但只要一排序,时间飙升至6s,而且行内视图也无法对排序进行优化,我还以为没救了,不过我还是把语句发给了rh。

最后一次优化(相比倒数第二次order 和 limit放到T5里)
我给他解释我优化的SQL语句,他执行之后也发现分开执行都很快,不排序也很快,于是我们开始寻找解决办法。
他突然发现排序的字段都是第一张表里的字段,于是把排序放到了T5里面,执行后耗时由6s+变为2s+
都是18w数据,但是排序位置导致耗时不大相同,T5的数据量在18w+,T6的数据量在5k+,那么可以得出:
相同数据量的排序,和一行数据所有的字段数量有很大的关联
到此我们都很开心,但我突然发现数据不一样,于是有开始想办法,我正在绞尽脑汁想的时候,rh把limit也给移到T5里面,结果相同了:

这根据数据库系统的算法有关,早期版本的算法是自然的多个线程二分法,那个线程先查到满足条件的数据就先输出出来,这样就是乱序的,后期经过改进按照主键自然排序输出

由于此时的两个行内视图都是没有主键的,那么底层运用的应该就是多线程二分法查找,导致顺序混乱掉了,
T6也只是resource相关的信息,limit放到T5就可以了。

在这里插入图片描述

总结

至此,sql优化完毕,由8s+降到了2s+,得出以下慢sql优化经验:
1.用inner join显示链接取代where on 隐式链接
2.小表在前,大表在后,用小表驱动大表
3.生成的中间临时表时可指定字段,如果字段在索引中可避免回表
进阶:
1.多个表联查时尽量减少表联查处理的层数,能糅合在一起的尽量在一层中处理
2.对于行内视图排序造成的慢SQL,尽量保证排序的视图是最小范围的必要字段和排序字段,排序完成之后再去对应联查其他字段的信息,也就是尝试从表业务功能的层面尝试划分。
3.注意inner Jon,left join等的使用场景:

相关阅读:
SQL优化常用的几种方法
mysql的7种join(图码并茂,清晰易懂!)
【知识】MySQL索引原理及慢查询优化

  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值