前后端性能优化实践(含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 个技巧!(文末送书) 

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

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

相关文章

App Inventor 2 文本转数字

App Inventor 2 是弱语言类型,文本和数字之间不用刻意去转换,之间赋值就可以了。文本赋值给数字变量如下: 运行结果:124 注意:数字变量初始化的时候要给一个数字的初始值,表明它是数字。 如果文本中含有非…

系列三、事务

一、事务 1.1、概述 事务是数据库操作的基本单元,它是指逻辑上的一组操作,要么都成功,要么都失败。典型场景:转账,例如Jack给Rose转账1000元,转账成功:Jack账户的余额少1000元,Rose…

关于进制的转化

二进制转十进制: 🔰 方法一:二进制转十进制,用各数的码位与位权的乘积之和,说白了就是用从右到左的每个数去乘以2的幂次方(最右边是0),然后就所有的数相加。 补充:位权是…

<蓝桥杯软件赛>零基础备赛20周--第7周--栈和二叉树

报名明年4月蓝桥杯软件赛的同学们,如果你是大一零基础,目前懵懂中,不知该怎么办,可以看看本博客系列:备赛20周合集 20周的完整安排请点击:20周计划 每周发1个博客,共20周(读者可以按…

MFC所有控件介绍及基本使用

一、前言 本篇文档介绍了MFC控件的基本使用,同时提供了关于MFC控件使用的工程代码,程序界面如下图,有兴趣的可以到文档最后的链接处进行下载。 二、控件介绍 2.1 Button (按钮) 2.2 CheckBox(复选框&am…

【jvm】虚拟机之堆

目录 一、堆的核心概述二、堆的内存细分(按分代收集理论设计)2.1 java7及以前2.2 java8及以后 三、堆内存大小3.1 说明3.2 参数设置3.3 默认大小3.4 手动设置3.5 jps3.6 jstat3.7 OutOfMemory举例 四、年轻代与老年代4.1 说明 五、对象分配过程5.1 说明5…

电脑键盘推荐

一、键盘分类 (1)键位个数 目前有75,84,87,98,104,108的。 (2)薄膜键盘和机械键盘 薄膜键盘就是大多数办公室常见的键盘,主要打一个便宜,耐造…

Python武器库开发-前端篇之Html基础语法(二十九)

前端篇之Html基础语法(二十九) HTML 元素 HTML元素指的是HTML文档中的标签和内容。标签用于定义元素的类型&#xff0c;而内容则是元素所包含的内容。HTML元素由开始标签和结束标签组成&#xff0c;也可以是自闭合标签。 例如&#xff0c;下面是一个叫做<p>的HTML元素…

Android开发从0开始(服务)

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

全网最全图解Kafka适用场景

消息系统 消息系统被用于各种场景&#xff0c;如解耦数据生产者&#xff0c;缓存未处理的消息。Kafka 可作为传统的消息系统的替代者&#xff0c;与传统消息系统相比&#xff0c;kafka有更好的吞吐量、更好的可用性&#xff0c;这有利于处理大规模的消息。 根据经验&#xff…

ubuntu环境删除qtcreator方法

文章目录 方法1方法2方法3参考不同的安装方法,对应不同的删除方法 方法1 apt-get或者dpkg 方法2 QtCreatorUninstaller 方法3 MaintenanceTool

2023亚太杯数学建模C题思路分析 - 我国新能源电动汽车的发展趋势

1 赛题 问题C 我国新能源电动汽车的发展趋势 新能源汽车是指以先进技术原理、新技术、新结构的非常规汽车燃料为动力来源( 非常规汽车燃料指汽油、柴油以外的燃料&#xff09;&#xff0c;将先进技术进行汽车动力控制和驱动相结 合的汽车。新能源汽车主要包括四种类型&#x…

Linux下安装python3步骤:

1.下载Python3源码 你需要从Python官网下载Python3的源码包。本文以Python 3.9.9为例。你可以使用wget命令来下载源码包到你的Linux主目录中: wget https://www.python.org/ftp/python/3.9.9/Python-3.9.9.tgz2.编译和安装Python3 下载好源码包后&#xff0c;你需要解压它&…

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

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

ubuntu22.04中ros2 安装rosbridge

ros2 启动rosbridge&#xff1a; 要启动ROS2中的rosbridge&#xff0c;需要先安装ROS2的rosbridge_suite软件包。使用以下命令安装&#xff1a; 更新过可忽略 sudo apt-get update安装命令 sudo apt-get install ros--rosbridge-suite 注意&#xff1a; 将替换为正在使用的R…

深度学习图像风格迁移 - opencv python 计算机竞赛

文章目录 0 前言1 VGG网络2 风格迁移3 内容损失4 风格损失5 主代码实现6 迁移模型实现7 效果展示8 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习图像风格迁移 - opencv python 该项目较为新颖&#xff0c;适合作为竞赛课题…

uniapp高德、百度、腾讯地图配置 SHA1

uniapp高德、百度、腾讯地图配置 SHA1 当winr弹出cmd弹框后输入 keytool -list -v -keystore debug.keystore 显示keytool 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件。可以先看看是否有下载jdk且配置了环境变量&#xff0c;具体操作如下&#xff1a;keyto…

please upgrade numpy version to >=1.20

升级 upgrade numpy_升级numpy-CSDN博客 pip install numpy --upgrade 没有pip conda install numpy --upgrade 会报错 conda list numpy来查看numpy版本 似乎这个numpy要看numpy-base这个 似乎没有pip

【开源】基于JAVA的计算机机房作业管理系统

项目编号&#xff1a; S 017 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S017&#xff0c;文末获取源码。} 项目编号&#xff1a;S017&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 登录注册模块2.2 课程管理模块2.3 课…

K8S如何部署ActiveMQ(单机、集群)

前言 大家好&#xff0c;在今天的讨论中&#xff0c;我们将深入研究如何将ActiveMQ迁移到云端&#xff0c;以便更好地利用Kubernetes的容器调度和资源管理能力&#xff0c;确保ActiveMQ的高可用性和可扩展性。 ActiveMQ是Apache开源组织推出的一款开源的、完全支持JMS1.1和J2…