一次显著的性能提升,从8s到0.7s
前言
最近我在公司优化了一些慢查询SQL,积累了一些SQL调优的实战经验。
我之前写过一些SQL优化相关的文章《聊聊SQL优化的15个小技巧》和《explain | 索引优化的这把绝世好剑,你真的会用吗?》,在全网广受好评。
这篇文章从实战的角度出发,给大家分享一下如何做SQL调优。
经过两次优化之后,慢SQL的性能显著提升了,耗时从8s优化到了0.7s。
现在拿出来给大家分享一下,希望对你会有所帮助。
1 案发现场
前几天,我收到了一封报警邮件,提示有一条慢查询SQL。
我打开邮件查看了详情,那条SQL大概是这样的:
SELECT count(*)
FROM spu s1
WHERE EXISTS (
SELECT *
FROM sku s2
INNER JOIN mall_sku s3 ON s3.sku_id = s2.id
WHERE s2.spu_id = s1.id
AND s2.status = 1
AND NOT EXISTS (
SELECT *
FROM supplier_sku s4
WHERE s4.mall_sku_id = s3.id
AND s4.supplier_id = 123456789
AND s4.status = 1
)
)
这条SQL的含义是统计id=123456789的供应商,未发布的spu数量是多少。
这条SQL的耗时竟然达标了8s,必须要做优化了。
我首先使用explain关键字查询该SQL的执行计划,发现spu表走了type类型的索引,而sku、mall_sku、supplier_sku表都走了ref类型的索引。
也就是说,这4张表都走了索引。
不是简单的增加索引,就能解决的事情。
那么,接下来该如何优化呢?
2 第一次优化
这条SQL语句,其中两个exists关键字引起了我的注意。
一个exists是为了查询存在某些满足条件的商品,另一个not exists是为了查询出不存在某些商品。
这个SQL是另外一位已离职的同事写的。
不清楚spu表和sku表为什么不用join,而用了exists。
我猜测可能是为了只返回spu表的数据,做的一种处理。如果join了sku表,则可能会查出重复的数据,需要做去重处理。
从目前看,这种写性能有瓶颈。
因此,我做出了第一次优化。
使用join + group by组合,将sql优化如下:
SELECT count(*) FROM
(
select s2.spu_id from spu s1
inner join from sku s2
inner join mall_sku s3 on s3.sku_id=s2.id
where s2.spu_id=s1.id and s2.status=1
and not exists
(
select * from supplier_sku s4
where s4.mall_sku_id=s3.id
and s4.supplier_id=...
)
group by s2.spu_id
) a
文章中有些相同的条件省略了,由于spu_id在sku表中是增加了索引的,因此group by的性能其实是挺快的。
这样优化之后,sql的执行时间变成了2.5s。
性能提升了3倍多,但是还是不够快,还需要做进一步优化。
3 第二次优化
还有一个not exists可以优化一下。
如果是小表驱动大表的时候,使用not exists确实可以提升性能。
但如果是大表驱动小表的时候,使用not exists可能有点弄巧成拙。
这里exists右边的sql的含义是查询某供应商的商品数据,而目前我们平台一个供应商的商品并不多。
于是,我将not exists改成了not in。
sql优化如下:
SELECT count(*) FROM
(
select s2.spu_id from spu s1
inner join from sku s2
inner join mall_sku s3 on s3.sku_id=s2.id
where s2.spu_id=s1.id and s2.status=1
and s3.id not IN
(
select s4.mall_sku_id
from supplier_sku s4
where s4.mall_sku_id=s3.id
and s4.supplier_id=...
)
group by s2.spu_id
) a
这样优化之后,该sql的执行时间下降到了0.7s。
之后,我再用explain关键字查询该SQL的执行计划。
发现spu表走了全表扫描,sku表走了eq_ref类型的索引,而mall_sku和supplier_sku表走了ref类型的索引。
可以看出,有时候sql语句走了4个索引,性能未必比走了3个索引好。
多张表join的时候,其中一张表走了全表扫描,说不定整个SQL语句的性能会更好,我们一定要多测试。
说实话,SQL调优是一个比较复杂的问题,需要考虑的因素有很多,有可能需要多次优化才能满足要求。
最后说一句(求关注,别白嫖我)
如果这篇文章对您有所帮助,或者有所启发的话,帮忙扫描下发二维码关注一下,您的支持是我坚持写作最大的动力。
求一键三连:点赞、转发、在看。
关注公众号:【苏三说技术】,在公众号中回复:面试、代码神器、开发手册、时间管理有超赞的粉丝福利,另外回复:加群,可以跟很多BAT大厂的前辈交流和学习。
一次显著的性能提升,从8s到0.7s的更多相关文章
- C# 程序性能提升篇-2、类型(字段类型、class和struct)的错误定义所影响性能浅析
前景提要: 编写程序时,也许你不经意间,就不知不觉的定义了错误的类型,从而发生了额外的性能消耗,从而降低了效率,不要说就发生那么一次两次,如果说是程序中发生了循环.网络程序(不断请求处理的)等这些时候 ...
- SQL Server 2014里的性能提升
在这篇文章里我想小结下SQL Server 2014引入各种惊艳性能提升!! 缓存池扩展(Buffer Pool Extensions) 缓存池扩展的想法非常简单:把页文件存储在非常快的存储上,例如S ...
- mapreduce性能提升2
mapreduce性能提升2mapreduce性能提升2mapreduce性能提升2
- YbSoftwareFactory 代码生成插件【二十一】:Web Api及MVC性能提升的几个小技巧
最近在进行 YbSoftwareFactory 的流程功能升级,目前已经基本完成,现将用到的一些关于 Web Api 及 MVC 性能提升的一些小技巧进行了总结,这些技巧在使用.配置上也相当的简单,但 ...
- 在PYTHON中使用StringIO的性能提升实测(更新list-join对比)
刚开始学习PYTHON,感觉到这个语言真的是很好用,可以快速完成功能实现. 最近试着用它完成工作中的一个任务:在Linux服务器中完成对.xml.gz文件的解析,生成.csv文件,以供SqlServe ...
- 揭秘Sql2014新特性-tempdb性能提升
一直以来,在高负载,复杂的生产环境中,tempdb的压力是成为整个实例瓶颈的重要因素之一.微软的工程师们也在各个版本中不断优化它的使用.到了Sql Server2014又有了新的特性使其性能得temp ...
- paip.cache 缓存架构以及性能提升总结
paip.cache 缓存架构以及性能提升总结 1 缓存架构以及性能(贯穿读出式(LookThrough) 旁路读出式(LookAside) 写穿式(WriteThrough) 回写式 ...
- C# 程序性能提升篇-1、装箱和拆箱,枚举的ToString浅析
前景提要: 编写程序时,也许你不经意间,就不知不觉的使程序代码,发生了装箱和拆箱,从而降低了效率,不要说就发生那么一次两次,如果说是程序中发生了循环.网络程序(不断请求处理的)等这些时候,减少装箱和拆 ...
- 天天动听MP3解码器性能提升50%
天天动听今日升级提醒,发现有一句 “使用新的MP3解码器,性能提升50%”,太惊讶了. 之前版本的MP3解码器使用libmpg123,效果已经是MP3解码器中非常不错的了. 50%的提升,应该不仅仅是 ...
- 重复造轮子感悟 – XLinq性能提升心得
曾经的两座大山 1.EF 刚接触linq那段时间,感觉这家伙好神奇,语法好优美,好厉害.后来经历了EF一些不如意的地方,就想去弥补,既然想弥补,就必须去了解原理.最开始甚至很长一段时间都搞不懂IQue ...
随机推荐
- SpringSecurity1: spring boot web 样例快速体验
本文只讲操作实践,不讲原理,这样对于想快速搭建起一个基于SpringSecurity的Web项目的朋友们而言,比较友好.文章主要由两部分构成: 快速演示样例 所有账户和授权数据均基于内存,能在极短的时 ...
- 论文解读(SimGCL)《Are Graph Augmentations Necessary? Simple Graph Contrastive Learning for Recommendation》
Note:[ wechat:Y466551 | 可加勿骚扰,付费咨询 ] 论文信息 论文标题:Are Graph Augmentations Necessary? Simple Graph Contr ...
- 高级SQL分析函数-窗口函数
摘要:本文由葡萄城技术团队于博客园原创并首发.转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 前言 SQL语句中,聚合函数在统计业务数据结果时起到了重要作用 ...
- 形象谈JVM-第三章-即时编译器优化技术
即时编译器优化技术一览: 相信许多同学看完这个表格,脑子里面嗡嗡的,这些名字也是晦涩难懂,要实现这些优化的技术确实有比较大的难度,但是咱们只是学习,去理解这些技术,其实并不难,下面咱们直接开讲. 首先 ...
- ENVI+ERDAS实现Hyperion叶绿素含量反演:经验比值法、一阶微分法
本文介绍基于ENVI与ERDAS软件,依据Hyperion高光谱遥感影像,采用经验比值法.一阶微分法等,对叶绿素含量等地表参数加以反演的具体操作. 目录 1 前期准备与本文理论部分 1.1 几句闲谈 ...
- Midjourney的一些学习心得:如何高效的图生图
注意本文没有什么长篇大论,全部是自己的学习心得. 心得体会:如何图生图 今天在一篇midjourney看到好图应该怎么抄. 相信经常会看到好图也想要的,但是要么抄不出感觉,要么抄过来把水印也抄了,这一 ...
- 《SQL与数据库基础》14. 存储过程 · 存储函数
目录 存储过程 基本语法 变量 系统变量 用户定义变量 局部变量 if判断 参数 case判断 while循环 repeat循环 loop循环 游标 条件处理程序 存储函数 本文以 MySQL 为例 ...
- 揭秘ChatGPT,如何打造自己的自定义指令
一.ChatGPT-0720更新 又在深夜,正要打开ChatGPT官网测试下pdf对话功能,发现ChatGPT又有更新.本次更新总结有2点: 1.对于Plus用户,GPT-4的使用限额从25条/3h提 ...
- HTML一键打包APK工具最新版1.9.2更新(附下载地址)
HMTL网址打包APK,可以把本地HTML项目, Egret游戏,网页游戏,或者网站打包为一个安卓应用APK文件,无需编写任何代码,也无需配置安卓开发环境,支持在最新的安卓设备上安装运行. 打包软件会 ...
- Vue源码学习(六):(支线)渲染函数中with(),call()的使用以及一些思考
好家伙, 昨天,在学习vue源码的过程中,看到了这个玩意 嘶,看不太懂,研究一下 1.上下文 这段出现vue模板编译的虚拟node部分 export function renderMixin( ...