一、概要
前提:
1、数据库SQL: 已经优化到极致,仍然查询慢
2,数据库语句有可拆分查询的空间
3、数据量大、接口访问时间过长
方案:
1、优化for循环体内,存在访问数据库的代码
2、使用并行流进行stream分组优化 (多线程)
3、使用并行流优化for循环(多线程)
4、使用多线程优化数据库查询速度
二、案例说明
1、需求格式(所有企业下所有排口以及各个排口的所有日数据)
2,性能差的写法(禁止使用 )
此种写法双重for循环 还进行访问数据库查询,会严重导致查询效率,我们需要进行提取。
3、优化方案1:提取for循环内置查询,流分组操作 ![](https://img-blog.csdnimg.cn/direct/0dd576598e93455cb1a3d4f09a31c6f8.png)
4、优化方案2:分组并行流优化、for循环并行流优化
方案1,优化完毕如果接口优化完毕还不能满足要求,这些可以发现大数据量分组感觉比较慢的问题,for循环也比较费时间.所以现在对这2个进行优化,数据量小可以忽略
For循环采用iava8的并行流循环(底层都是多线程处理,并收集合并数据)
分组采用并行流分组 (底层都是多线程处理,并收集合并数据)
5、优化方案3:对数据库查询进行优化
上面2种方案,应该能满足大多接口响应慢的问题。不过部分业务仍加载慢: 其中根本原因在于数据语句查询过慢,而数据库语句已经改无可改。那证明数据库每条语句查询时间已经比较固定了。目前就只能并行处理各个sql。
例如: sql1要花费 5秒
sql2 要花费10秒
sql3要花费6秒
在sql无法优化的情况下 我们只能保证数据在10s完成查询。不能进行累加操作花费21s
2、调用异步线程类收集结果
6、使用到@Async注解,必须自定义线程池
@Async异步方法默认
核心线程数为8
最大队列和最大线程都是Integer.MAX_VALUE
创建线程的前提条件是队列填满时,默认的配置永远不会填满
如果有@Async这个注解的方法长期占用线程,在核心8个线程数满了后,新的调用就会进入队列,外部表现没有执行。
项目增加线程池的配置类(有配置的可不用增加):具体配置文件见SVN
优化方案3的异步类: @Async注解指定使用自定义线程池
三、结语
本文主要优化方式,都是结合多线程进行优化并推崇用iava8的对应写法。具体iava8语法不了解的可以自行寻找资料进行学习
如果数据量少的情况下用foreach的循环写法Stream流循环针对数据量大的情况下会更具优势,小数据不明显