前后端性能优化实践(含Java代码部分、数据库部分、React前端部分)

最近的一个大屏报表统计的接口查询速度很慢,耗时近一分钟左右,数据量级只是700万左右,但很慢,最后优化到4秒左右,客户还能接受,但其实还可以在优化,先这样吧,简单记录下。这次主要优化的部分数据库和Java代码部分,前端的很少。

一、数据库

优化先从浏览器的接口调用看,查看到耗时近1分钟,根据接口名称查询对应的Java代码,发现代码中存在两个SQL的调用,顺着引用找到SQL语句,一看是两个都是关联查询的SQL,其中一个还是关联了5张表,复制出来后,到SQL端执行,确实很慢。

数据库优化很好用的两个命令是EXPLAINEXPLAIN ANALYZE命令,都是加载查询语句前面,用于分析查询计划查询实际执行情况的。

然后是使用EXPLAIN命令查看查询计划的的信息,判断是否有需要添加或修改的索引。

使用案例:

---只需将 EXPLAIN 关键字加在查询语句开头就行 

EXPLAIN SELECT COUNT(DISTINCT h.id)
FROM test h
JOIN test2 s ON h.id = s.father_id
WHERE s.first_classify = 'QC' ;

执行结果示例

EXPLAIN 命令可以用来分析 SQL 查询语句的执行计划,它返回一组字段信息,提供了有关查询的重要性能指标和执行计划的详细信息。下面是 EXPLAIN 命令返回的字段信息的介绍:

  1. id:查询的标识符,用于标识查询中的每个操作步骤。如果查询有多个操作步骤,id 可能会有多个数字,表示操作步骤的执行顺序。

  2. select_type:操作步骤的类型,表示查询的类型。常见的类型有 SIMPLE(简单查询)、PRIMARY(主查询)、SUBQUERY(子查询)、DERIVED(派生表查询)等。

  3. table:操作步骤涉及的表的名称。

  4. partitions:操作步骤使用的分区。

  5. type:访问表的方式,表示查询使用的访问方法。常见的类型有 const(常量表)、eq_ref(唯一索引查找)、ref(非唯一索引查找)、range(范围查找)、index(索引扫描)、all(全表扫描)等。一般来说,访问方法从最好到最差的顺序是:const、eq_ref、ref、range、index、all。

  6. possible_keys:可能应用于该操作步骤的索引列表。

  7. key:实际应用于该操作步骤的索引。

  8. key_len:索引字段的长度。

  9. ref:操作步骤使用的索引字段或常量与表之间的关联。

  10. rows:操作步骤扫描的行数估计。

  11. filtered:操作步骤的行过滤百分比。

  12. Extra:附加信息,提供了关于操作步骤的其他信息,例如是否使用了临时表、是否使用了文件排序等。

这些字段信息可以了解查询的执行计划和性能瓶颈,从而进行性能优化和调整。通过分析这些信息,可以确定是否需要添加索引、优化查询条件、重构查询语句等来提高查询性能。

不同的数据库管理系统(如MySQL、PostgreSQL等)可能会略有不同的字段信息和含义。

关键信息是type类型,尽量少用全表扫描。possible_keys,在适合的字段上加上索引。索引的是使用是用空间换时间。

下面是使用EXPLAIN ANALYZE 命令执行查询结果分析

---只需将 EXPLAIN ANALYZE 关键字加在查询语句开头就行 

EXPLAIN ANALYZE SELECT COUNT(DISTINCT h.id)
FROM test h
JOIN test2 s ON h.id = s.father_id
WHERE s.first_classify = 'QC' ;

执行结果,如果你看不懂,可以直接把查询结果丢给ChatGPT让它给你分析,并逐行注释。

-> Aggregate: count(distinct h.id)  (cost=1193743.16 rows=1) (actual time=4594.609..4594.609 rows=1 loops=1)
    -> Nested loop inner join  (cost=824307.99 rows=3694352) (actual time=0.359..2941.550 rows=1277716 loops=1)
        -> Covering index scan on h using id_idx  (cost=33565.75 rows=257665) (actual time=0.136..76.075 rows=272267 loops=1)
        -> Covering index lookup on s using idx_father_id_first_classify (father_id=h.id, first_classify='F41A01')  (cost=1.64 rows=14) (actual time=0.008..0.010 rows=5 loops=272267)

 

EXPLAIN ANALYZE 命令是一种用于分析 SQL 查询语句执行计划和实际执行时间的命令。它返回的字段信息包括 EXPLAIN 命令的字段信息,同时还包括以下字段:

  1. QUERY PLAN:查询执行计划的详细信息,包括操作步骤、访问方法、索引使用等。

  2. Planning Time:查询规划阶段的时间,表示生成查询执行计划所花费的时间。

  3. Execution Time:查询执行阶段的时间,表示实际执行查询所花费的时间。

  4. Actual Rows:实际扫描的行数,表示查询实际扫描的行数。

  5. Actual Loops:实际循环次数,表示查询实际执行的循环次数。

  6. Actual Startup Time:实际开始执行查询的时间。

  7. Actual Total Time:实际执行查询的总时间。

  8. Actual Time:实际执行查询的时间,以毫秒为单位。

EXPLAIN ANALYZE 命令返回的字段信息可以帮助您更全面地了解查询的执行计划和实际执行情况。通过分析这些信息,可以确定查询的性能瓶颈、优化查询计划、减少查询执行时间等。同时,还可以比较不同查询语句的执行效果,选择性能最佳的查询方式。

最后通过ANALYZE TABLE 命令来优化下对应的表,

---只需将 EXPLAIN TABLE 关键字加在表名开头就行 
ANALYZE TABLE test;

ANALYZE TABLE 命令是用于分析和收集数据库表统计信息的命令。它的主要作用是帮助优化查询性能和执行计划。

ANALYZE TABLE 命令会完成以下任务:

  1. 优化查询计划:通过分析表的统计信息,数据库管理系统可以更准确地估计查询的成本和选择最优的执行计划。

  2. 选择合适的索引:通过分析表的索引长度和数据分布情况,可以判断是否需要创建或删除索引,以及选择合适的索引类型和列顺序。

  3. 优化存储空间:通过分析表的行数和平均行长度,可以估计表的总大小,并根据需要进行存储空间的调整。

  4. 检测表的完整性:通过分析更新时间和自增值,可以检测表的数据是否完整,并及时发现可能存在的问题。

数据库的查询,通过加索引大部分都能解决,在这个过程中善于用ChatGPT来帮助解决很重要。

二、Java程序代码

下面是程序代码的部分,原本的程序代码并不是我写的,打开看了之后,有两个执行查询的代码段是可以同时执行的,所以改成并发执行

程序上改后,接口时间就减少一半了,接口时间来到了4.5秒左右,但其实还是慢。

三、前端React代码

在改改前端,前端的话,可以把这个接口的查询放在最开始执行,以减少用户使用的等待延迟感受。前段端代码就省略了。下次有机会在写吧。

四、总结拓展

性能优化某种意义上是对资源取舍利用的问题。通常是就是空间和时间的互换与取舍。

以下是我收集到的常见的6种互换手段。

1、索引

索引的原理是拿额外的存储空间换取查询时间,增加了写入数据的开销,但使读取数据的时间复杂度一般从O(n)降低到O(logn)甚至O(1)。

在数据集比较大时,不用索引就像从一本没有目录而且内容乱序的新华字典查一个字,得一页一页全翻一遍才能找到;用索引之后,就像用拼音先在目录中先找到要查到字在哪一页,直接翻过去就行了。书籍的目录是典型的树状结构。

2、缓存

缓存优化性能的原理和索引一样,是拿额外的存储空间换取查询时间。Phil Karlton 曾说过:计算机科学中只有两件困难的事情:缓存失效和命名规范。缓存的使用除了带来额外的复杂度以外,还面临如何处理缓存失效的问题。

3、压缩

压缩的原理消耗计算的时间,换一种更紧凑的编码方式来表示数据。对数据的压缩虽然消耗了时间来换取更小的空间存储,但更小的存储空间会在另一个维度带来更大的时间收益。

能减少的就减少:

  • JS打包过程“摇树”,去掉没有使用的文件、函数、变量;

  • 开启HTTP/2和高版本的TLS,减少了Round Trip,节省了TCP连接,自带大量性能优化;

  • 减少不必要的信息,比如Cookie的数量,去掉不必要的HTTP请求头;

  • 更新采用增量更新,比如HTTP的PATCH,只传输变化的属性而不是整条数据;

  • 缩短单行日志的长度、缩短URL、在具有可读性情况下用短的属性名等等;

  • 使用位图和位操作,用风骚的位操作最小化存取的数据。典型的例子有:用Redis的位图来记录统计海量用户登录状态;布隆过滤器用位图排除不可能存在的数据;大量开关型的设置的存储等等。

能删除的就删除:

  • 删掉不用的数据;

  • 删掉不用的索引;

  • 删掉不该打的日志;

  • 删掉不必要的通信代码,不去发不必要的HTTP、RPC请求或调用,轮询改发布订阅;

  • 终极方案:砍掉整个功能。

4、预取

预取通常搭配缓存一起用,其原理是在缓存空间换时间基础上更进一步,再加上一次“时间换时间”,也就是:用事先预取的耗时,换取第一次加载的时间。

当可以猜测出以后的某个时间很有可能会用到某种数据时,把数据预先取到需要用的地方,能大幅度提升用户体验或服务端响应速度。

5、削峰填谷

削峰填谷的原理也是“时间换时间”,谷时换峰时。

削峰填谷与预取是反过来的:预取是事先花时间做,削峰填谷是事后花时间做。就像三峡大坝可以抗住短期巨量洪水,事后雨停再慢慢开闸防水。软件世界的“削峰填谷”是类似的,只是不是用三峡大坝实现,而是用消息队列、异步化等方式。

6、批量处理

批量处理同样可以看成“时间换时间”,其原理是减少了重复的事情,是一种对执行流程的压缩。以个别批量操作更长的耗时为代价,在整体上换取了更多的时间。

  • 前端把所有文件打包成单个JS,大部分时候并不是最优解。Webpack提供了很多分块的机制,CSS和JS分开、JS按业务分更小的Chunk结合懒加载、一些体积大又不用在首屏用的第三方库设置external或单独分块,可能整体性能更高。不一定要一批搞定所有事情,分几个小批次反而用户体验的性能更好。

  • Redis的MGET、MSET来批量存取数据时,每批大小不宜过大,因为Redis主线程只有一个,如果一批太大执行期间会让其他命令无法响应。经验上一批50-100个Key性能是不错的,但最好在真实环境下用真实大小的数据量化度量一下,做Benchmark测试才能确定一批大小的最优值。

  • MySQL、Oracle这类RDBMS,最优的批量Insert的大小也视数据行的特性而定。我之前在2U8G的Oracle上用一些普遍的业务数据做过测试,批量插入时每批5000-10000条数据性能是最高的,每批过大会导致DML的解析耗时过长,甚至单个SQL语句体积超限,单批太多反而得不偿失。

  • 消息队列的发布订阅,每批的消息长度尽量控制在1MB以内,有些云服务商提供的消息队列限制了最大长度,那这个长度可能就是性能拐点,比如AWS的SQS服务对单条消息的限制是256KB。

 

还有与提升并行能力有点关的4中方式:

  1. 榨干计算资源
  2. 水平扩容
  3. 分片
  4. 无锁

参考文献

性能优化的 10 个技巧!(文末送书) 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【LeetCode:2824. 统计和小于目标的下标对数目 | 模拟+二分】

🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…

分布式篇---第四篇

系列文章目录 文章目录 系列文章目录前言一、分布式ID生成有几种方案?二、幂等解决方法有哪些?三、常见负载均衡算法有哪些?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给…

【机器学习 | 白噪声检验】检验模型学习成果 检验平稳性最佳实践,确定不来看看?

🤵‍♂️ 个人主页: AI_magician 📡主页地址: 作者简介:CSDN内容合伙人,全栈领域优质创作者。 👨‍💻景愿:旨在于能和更多的热爱计算机的伙伴一起成长!!&…

java堆文件排查

技术主题 在之前的开发的一个项目中,因为程序的一个bug,导致一些引用的对象一直没有回收,从而导致堆内存一直在增大,老年代一直在增大,老年代进行堆积,后来的排查思路是通过dump堆的文件,然后对…

上门预约小程序开发优势

想要放松身心,享受按摩的舒适感?那就需要一个专业的按摩师来上门服务。我们开发的预约按摩小程序app系统,汇聚各类上门按摩服务,包括推拿SPA、小儿推拿、中医等,为您提供高价值、高标准的养生健康体验。24小时随时提供…

「树形」样式,数据关联超便捷丨三叠云

树形样式 路径 表单设计 >> 字段属性 功能简介 「表单关联」的数据列表样式支持「树形」样式功能,关联数据选择时通过「树形」的列表方式进行数据选择,提高生产效率。 使用场景: 可以通过树形列表样式展示部门、子部门、成员的树形…

鸿蒙系统使用hdc_std.exe使用身份证读卡器等外设USB获得权限方法

hdc_std.exe是OpenHarmony 的命令行工具,由于使用的开源鸿蒙开发板上面没有文件管理器,所以无法通过U盘等方式进行安装.hap应用。 下面是使用hdc_std.exe安装身份证读卡器的步骤: 1、hdc_std.exe放桌面,然后WINR,打开…

网站定制开发有哪些分类?|企业软件app小程序定制

网站定制开发有哪些分类?|企业软件app小程序定制 网站定制开发是指根据客户需求,为其量身定制设计和开发的网站服务。目前,网站定制开发主要分为以下几个分类: 1. 静态网站定制开发:静态网站是由HTML、CSS和JavaScrip…

表格视图,支持数据直接编辑丨三叠云

表格视图 路径 表单设置 >> 视图设置 功能简介 新增用户可以直接表格视图中直接点击编辑数据。管理员开启「列表编辑」后,用户无需再点击进入数据详情,可直接在列表中编辑数据,节约用户修改数据的时间。 使用场景: 通…

CMS指纹识别方式

一、手工识别 1.robots.txt文件 robots.txt文件我们写过爬虫的就知道,这个文件是告诉我们哪些目录是禁止爬取的。但是大部分的时候我们都能通过robots.txt文件来判断出cms的类型 如: 从wp路径可以看出这个是WordPress的cms 这个就比较明显了直接告诉我们是PageAdmin cms 也…

详解Java中的异常体系机构(throw,throws,try catch,finally)

目录 一.异常的概念 二.异常的体系结构 三.异常的处理 异常处理思路 LBYL:Look Before You Leap EAFP: Its Easier to Ask Forgiveness than Permission 异常抛出throw 异常的捕获 提醒声明throws try-catch捕获处理 finally的作用 四.自定义异常类 一.异…

累计定点160+车型,商汤绝影凭什么领跑规模化量产?

2023广州车展火热进行,智能化技术加速“内卷”。 商汤绝影多款合作量产车型亮相2023广州车展,包括昊铂 GT、传祺ES9、E8系列和本田雅阁、捷途旅行者、极氪X等,全方位呈现在智能驾驶和智能座舱领域的最新成果,以AI“新科技”&…

RTL8762x芯片避坑总结之1——用GPIO模拟I2C

1. 使用GPIO模拟I2C: 1.1 按常规逻辑 在输出第1个数据,切换为输入读取ACK后,切回输出无效,不能输出数据: 1.2 在切换输入输出前,需要对Pad重新进行配置 重新配置后,输入输出切换成功&#xf…

Android开发从0开始(服务)

Android后台运行的解决方案,不需要交互,长期运行。 服务基础框架: public class MyService extends Service { public MyService() { } Override public IBinder onBind(Intent intent) { //activity与service交互(需要继…

多actor实体组合并统一应用变换_vtkAssembly

开发环境: Windows 11 家庭中文版Microsoft Visual Studio Community 2019VTK-9.3.0.rc0vtk-example参考代码 demo解决问题:创建了一个球体和立方体的三维可视化,将它们组合成一个装配体,应用变换,调整不透明度&#…

美国汽车零部件巨头 AutoZone 遭遇网络攻击

Security Affairs 网站披露,美国汽车配件零售商巨头 AutoZone 称其成为了 Clop MOVEit 文件传输网络攻击的受害者,导致大量数据泄露。 AutoZone 是美国最大的汽车零配件售后市场经销商之一,在美国、墨西哥、波多黎各、巴西和美属维尔京群岛经…

opencv-Meanshift 和 Camshift 算法

MeanShift 和 CamShift 都是用于目标跟踪的算法,基于颜色直方图的方法。它们主要用于在视频序列中追踪运动的对象。 MeanShift(均值漂移): 原理: MeanShift 算法的基本思想是通过不断调整窗口的中心,使得窗口中的样本点的平均值向…

【前端】让列表像Excel单元格一样编辑

前言 领导说了一堆的话,最后总结一句就是客户很懒,客户的员工更加懒。 本着让别人节省时间的原则,提倡出了让列表和Excal的单元格一样,不仅看数据还可以随时更改数据。 查资料 根据 Jeecg-Vue3 源码介绍,从而知道是基于 Vben Admin 开源项目进行改造的。 因此在 Vben…

JavaScript之DOM操作

第一章 API介绍 ​API是一种事先定义好的函数,用来提供应用程序与开发人员基于某软件或硬件得以访问的一组例程,而又无需访问源码,或理解内部工作机制的细节。 ​Web API接口:浏览器提供的一系列操作浏览器功能和页面元素的API(BO…

opencv-背景减除

背景减除(Background Subtraction)是一种用于从视频序列中提取前景对象的计算机视觉技术。该技术的主要思想是通过建模和维护场景的背景,从而检测出在不同时间点出现的前景对象。 OpenCV 提供了一些用于背景减除的函数,其中最常用…