V-xin:ruyuanhadeng获得600+页原创精品文章汇总PDF

前 言

通过前几期文章的积累,现在我们的理论知识已经极为扎实了,这个时候就可以动手开始sql优化了,sql优化是非常重要,因为即使再好的MySQL设计架构,也扛不住一个频繁查询的垃圾sql语句。

关于sql的优化,我们也是有一定的原则和先后顺序的,大体的步骤的我们用一张流程图来看一下:

总体呢,大概可以分为以下几个步骤:

(1)首先,我们得要看下sql语句中是否有join语句,比如内连接查询inner join,外连接查询 left join right join等;因为join语句一般都涉及到跨表查询了,所以首先我们得要为join语句中,负责连接两张表的字段创建索引,这样的话可以利用索引加快两张表关联的速度。

(2)接下来,我们会再看一下sql语句中的where语句,我们可以根据当前表中的数据量,以及where语句的过滤条件,预估下查询结果的数据量是否会很大,如果数据量很大的话,查询的速度肯定就会很慢,所以,为了提高sql语句的执行效率,我们得要为where语句中过滤字段单独创建索引。

(3)当我们把join语句以及where语句中的字段优化完之后,就可以来看一下其他的一些细节部分,比如sql语句中如果使用了聚合函数,或者对查询的结果进行了排序,那么,一般我们都建议为聚合函数中的字段,以及排序的字段都创建索引,让这些操作利用索引速度更快点。

sql优化中不管是对where语句、聚合函数、还是排序操作的优化,优化起来相对而言会简单点,为对应的字段创建合适的索引就可以了,但是,join语句这块的优化涉及到一些比较重要的原理,我们还是有必要来看下的。

简单来说,在mysql中使用join语句关联2张表的话,比如执行这条sql:

select * from order_info t1 left join order_item_detail t2 on t1.order_no = t2.order_no

这个时候,join关联查询的过程是什么样子的呢?其实,这个就取决于当前join语句用到的算法了,join语句一共有3种算法,最基础的是Simple nested loop算法,接下来,我们一起来看下。


Simple nested loop算法

Simple nested loop算法,说白了就是一个双重for循环遍历的算法,Simple nested loop算法匹配的过程是这样的:

从左边的驱动表order_info中,每取出一条记录都要遍历一遍被驱动表order_item_detail,说白了就是一个双重for循环。

如果驱动表和被驱动表中都有100条数据的话,那么此时就需要匹配 100 * 100 = 10000次,可见效率是非常低的,所以,MySQL并没有选择使用 Simple nested loop 算法,而是使用了优化后的Block nested loop 算法。


Block nested loop 算法

Block nested loop 算法对 Simple nested loop 算法进行了优化,它引入了 join buffer,join buffer 主要用于优化不带索引条件的 join 查询,它会缓存连接过程中用到的字段,这样可以有效减少匹配次数,就像这样:

可以看到,Block nested loop的优化思路,是减少被驱动表的匹配次数,它主要是通过一次性缓存驱动表的多条数据,以此来减少被驱动表的匹配次数,从而可以达到提升性能的目的。

需要注意的是,MySQL提供了一个参数join buffer_size,它是用来控制 join buffer 大小的,而MySQL默认的join_buffer_size 是 256K,所以如果驱动表的数据太多的话,默认的join buffer可能一次性放不下全部的数据。

这个时候,join buffer就会采用分段缓存的机制来缓存驱动表的数据,但是这种分段缓存方式的性能,是比一次性缓存全部数据要差一些的。

所以,我们可以通过join_buffer_size参数,适当调大join buffer的大小,使join buffer可以一次性放下驱动表的所有数据,这样可以提升join的性能。


Index nested loop算法

最后还有一种Index nested loop算法:

它的优化思路主要是减少被驱动表数据的匹配次数, 就是驱动表直接与被驱动表的索引进行匹配,这样就不用和被驱动表的每条记录比较了。

原来的匹配次数为:驱动表行数 * 被驱动表行数,而现在变成了:驱动表行数 * 被驱动表索引的高度,这样就极大的减少了被驱动表的匹配次数,极大的提升了join的性能。

如果join关联查询能使用到索引的话,MySQL就会使用Indexnestedloop算法,如果无法使用Indexnestedloop算法,MYSQL默认会使用Blocknestedloop算法。


到底能不能使用join?

好了,我们刚才了解了Simple nested loop 、 Block nested loop、Index nested loop 这三种算法,那么现在可以回答开头的问题了:到底能不能使用join?

其实,如果能用上被驱动表上的索引,说白了就是可以用上 Index nested loop 算法的话,是可以使用 join 的。

而如果使用的是 Block nested loop 算法的话,由于扫描行数和比较次数会比较多,所以会占用大量的系统资源,所以这种情况能不用join就不用join。

我们平常使用explain优化sql的时候,如果 explain 结果中的 Extra 字段,如果包含 ’ Using join buffer (Block Nested Loop) ’ 的话,这个时候就代表使用了 Block nested loop 算法了。

如果能使用上被驱动表上的索引的话,join还是可以使用的,这个时候基本不会影响性能,那么我们这里为什么要优化掉join呢?

主要由于2个原因,首先后边我们有分库分表的计划,所以为了有更好的扩展性,我们会优化掉join,其次MySQL是专门用来做数据存储的,所以,还是尽量不要把业务相关的逻辑放到MySQL层面来做。

所以基于这2个原因,我们会将单体应用版本的join给优化掉。


join关联查询优化实战

被驱动表order_no列未加索引

(1)join关联查询sql语句

可以看到,sql语句中,left join语句中,订单明细表是通过order_no字段和订单表关联的,此时驱动表order_info的order_no是加了索引的,而被驱动表order_item_detail的order_no字段没有添加索引

(2)看一下查询时间

此时order_info中的数据量为2500万条,而订单明细表 order_item_detail 的数据量是1亿条。

可以看到被驱动表order_item_detail没使用到索引时,查询效率是非常低下的。


优化:被驱动表order_no列添加索引

(1)为被驱动表添加索引

现在我们为被驱动表order_item_detail的order_no添加索引,添加索引sql如下:

create index inx_item_order_noon order_item_detail (order_no);

(2)再次查看join关联查询的时间

此时我们发现被驱动表order_item_detail的关联字段order_no用上索引后,查询效率提升的非常明显。


进一步优化:去掉join

此时我们为了更好的扩展性,需要将join关联查询给优化掉

(1)看下join优化后的代码:

拆分join,改成单表查询,内存中再组装数据

(2)看一下优化后的时间

可以看到,将join关联查询优化掉之后,我们除了可以获取到更大的扩展性外,可以发现对查询性能的提升也是非常大的。


被动向主动的转变,监控系统诞生

在sql优化这个例子中,这个问题是由DBA同学发现的,然后DBA同学将问题反馈给了我们,实际在工作中呢,也可能是产品同学发现订单信息查询页面有点慢,然后将问题反馈给我们。

不管是谁发现的,对于我们订单系统的开发人员来说都是非常被动的,因为我们不能及时主动的发现问题,比如某一个接口变慢了,我们不能及时知道,只能等别人反馈给我们,这样被动的发现问题,会在一定程度上扩大问题的影响。

为了解决这个问题,我们建立了一套完善的监控系统,这个监控系统呢,可以添加很多监控面板,比如我们可以添加订单的监控面板,订单监控面板中的核心指标包含:订单核心接口的请求次数、失败次数、TP50、TP99等等。

然后,为了及时发现问题,这个监控系统还集成了报警的功能,说白了就是针对某一个监控指标,我们会设置一个报警规则,比如每天的某一个时间段,在多少分钟内,失败请求超过多少,那么就会报警给对应的开发人员,报警方式呢,会分为2种,分别是报警电话和消息推送(推送给公司内部的办公聊天软件)

报警的时候为了避免开发人员的单点故障,报警接收人一般会添加多个,如果第一个人不接报警电话的话,那么就顺延给第二个人打电话,这样就可以最大程度的及时发现问题了,就可以真正的由被动转为主动了。

V-xin:ruyuanhadeng获得600+页原创精品文章汇总PDF

另外推荐儒猿课堂的1元系列课程给您,欢迎加入一起学习~

互联网Java工程师面试突击课(1元专享)

SpringCloudAlibaba零基础入门到项目实战(1元专享)

亿级流量下的电商详情页系统实战项目(1元专享)

Kafka消息中间件内核源码精讲(1元专享)

12个实战案例带你玩转Java并发编程(1元专享)

Elasticsearch零基础入门到精通(1元专享)

基于Java手写分布式中间件系统实战(1元专享)

基于ShardingSphere的分库分表实战课(1元专享)

千万数据量下的真实业务场景SQL性能优化!相关推荐

  1. 【云原生|实践指北】5:真实业务场景下云原生项目落地实践学习

    真实业务场景下云原生项目落地实践学习 写在前面的话 1.容器化的落地实践 搜题APP的云上之旅 2.Serverless的落地实践 某电商APP的Serverless改造之旅 3.云原生TKE的落地实 ...

  2. 现身说法:实际业务出发分析百亿数据量下的多表查询优化

    今天给大家带来的讨论主题是通过实战经验来对百亿数据量下的多表数据查询进行优化,俗话说的好,一切脱离业务的架构都是耍流氓,接下来我就整理一下今天早上微信群里石头哥给大家分享的百亿数据量多表查询架构以及优 ...

  3. 真实业务场景展现CAS原理的ABA问题及解决方案

    文章目录 阅读提示 CAS原理.ABA问题介绍 真实业务场景 如何解决ABA问题 CAS学习总结 阅读提示 本文将借助开保险柜的业务场景重点阐述误用AtomicBoolean引起的ABA问题,以及解决 ...

  4. 达观数据CTO纪达麒:小标注数据量下自然语言处理实战经验

    自然语言处理在文本信息抽取.自动审校.智能问答.情感分析等场景下都有非常多的实际应用需求,在人工智能领域里有极为广泛的应用场景.然而在实际工程应用中,最经常面临的挑战是我们往往很难有大量高质量的标注语 ...

  5. 一招教你解决大数据量下的各种报表使用问题

    在我们日常制作报表分析过程中,总会遇到各种问题.比如,报表底层数据日益增多.报表加载超慢,这些情况该怎么解决? 数据库是最常见的能处理大数据的计算方案,而永洪能利用数据库来完成数据计算.但是,有些报表 ...

  6. 大数据量下,身份证的查询优化

    大数据量下,身份证的查询优化 这里是测试练习采用select *,实际场景中还是使用所有字段的形式,这样也可以提高效率 方式一:身份证分别正向.逆向存储,使用like逆序模糊查询,满足最左匹配原则,索 ...

  7. 百万数据量下,使用延迟关联优化超大分页

    百万数据量下,使用延迟关联优化超大分页 MySQL 并不是跳过 offset 行,而是取 offset + N 行,然后返回放弃前 offset 行,返回 N 行,那当offset 特别大的时候,效率 ...

  8. 大数据量下水晶报表的实现及显示过程中的进度条显示讨论

    最近一段收到的反馈中,有几位是问到在应用程序中使用水晶报表时,大数据量情况下因为等待时间过长,给用户的感觉不好 所以想增加一个进度条,给用户一个比较直观的印象. 本文针对此问题而生,但是并没有一个像样 ...

  9. 以字节跳动内部 Data Catalog 架构升级为例聊业务系统的性能优化

    背景 字节跳动 Data Catalog 产品早期,是基于 LinkedIn Wherehows 进行二次改造,产品早期只支持 Hive 一种数据源.后续为了支持业务发展,做了很多修修补补的工作,系统 ...

最新文章

  1. 设置cl.exe环境变量
  2. dojo gridx修改表头
  3. 疯子的算法总结(七) 字符串算法之 manacher 算法 O(N)解决回文串
  4. java 自定义解码_[求助],java如何使用自定义注解对入参进行解密?
  5. layer模态窗简单使用
  6. 【转】Quartz.NET快速入门指南
  7. 锐捷长ping_锐捷交换机常用操作命令
  8. MapGIS10.3Desktop64位学习版带安装教程
  9. 企业开票信息税号查询API接口服务
  10. 从零开始的硬改路由器记录
  11. Gitbub远程仓库的访问
  12. linux中的last命令,linux系统中last命令的用法
  13. PowerDesigner工具栏消失恢复
  14. 服务器基础知识全解(汇总版)
  15. Zend 发送邮件报错
  16. 第一种可以用手机远程实时观看的网络摄像机,还带云台,报警,双向语音
  17. js两种拼接字符串方法
  18. 在设计齿轮时,如何选用合适的模数
  19. 将c语言程序转化成伪代码,「第9篇」「做编程题方法3」「来点伪代码」
  20. css文件的创建和使用

热门文章

  1. 我的域名注册踩坑指南
  2. 第七届全球云计算大会-中国站9月宁波举办
  3. suds对接web service
  4. lopatkin俄大神精简Windows 10 Enterprise 19041.331 20H1 Release x86-x64 EN-RU PIP
  5. 银河麒麟系统部署.net core环境
  6. 关于程序可移植性的问题
  7. 系统学习SSH(一)--SSH
  8. Win10家庭版远程桌面工具RDP Wrapper出现Not listening解决方案
  9. cocos2d-x 艺术字
  10. 数据流图-2(分层数据流图)