背手夹包剃炮头 2024-06-11 13:57 采纳率: 0%
浏览 5

两层循环里判断在修改数据 借口响应比较慢,怎么做才能让接口响应快一点!

这个是一个定时任务 请问下各位,这段代码该如何优化?目前是两层循环里判断在修改数据
,借口响应比较慢,怎么做才能让接口响应快一点!

public void regularlyRefreshTheNumberOfPeopleInTheRoom() {
        List<AmsRoom> amsRooms = amsRoomService.selectAmsRoomList(new AmsRoom());
        if (!CollectionUtils.isEmpty(amsRooms)) {
            for (AmsRoom amsRoom : amsRooms) {
                String roomNo = amsRoom.getRoomNo();
                List<TUOrder> tuOrderList = ituOrderService.selectGoldenSwanRoomNuber(roomNo);
                if (!CollectionUtils.isEmpty(tuOrderList)) {
                    amsRoom.setRoomPeoples(tuOrderList.size());
                } else {
                    amsRoom.setRoomPeoples(0);
                }
                int i = amsRoomService.updateAmsRoom(amsRoom);
            }
        }
    }

  • 写回答

3条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-06-11 13:57
    关注

    引自免费微信小程序:皆我百晓生

    面对接口响应慢的问题,尤其是当涉及大量数据处理时,可以考虑以下几个优化方向:

    1. 减少数据库交互次数:当前代码中,对于每个AmsRoom对象,都会执行一次查询操作来获取tuOrderList,这导致了数据库的多次访问。可以尝试将所有查询合并为一个批量查询,减少数据库的I/O操作。

    2. 异步处理:如果条件允许,可以将数据更新逻辑放入后台线程或队列中进行异步处理,这样不会阻塞主线程,提高接口响应速度。

    3. 缓存机制:引入缓存可以大大减少对数据库的依赖,尤其是在数据变化不频繁的情况下。使用缓存存储查询结果,并设置合理的过期时间,可以显著提升性能。

    4. 并行处理:利用多线程或并行流处理数据,可以同时处理多个AmsRoom对象,充分利用多核CPU的计算能力。

    基于以上思路,这里提供一种可能的优化方案,采用批量查询和异步处理相结合的方法:

    import java.util.Map;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.stream.Collectors;
    
    public class OptimizedService {
    
        private final ExecutorService executorService = Executors.newFixedThreadPool(10); // 创建固定大小的线程池
    
        public void regularlyRefreshTheNumberOfPeopleInTheRoom() {
            List<AmsRoom> amsRooms = amsRoomService.selectAmsRoomList(new AmsRoom());
            
            if (!CollectionUtils.isEmpty(amsRooms)) {
                // 使用房间号批量查询,将结果存储在Map中,key为房间号,value为人数
                Map<String, Integer> roomPeopleMap = amsRooms.stream()
                                                            .map(AmsRoom::getRoomNo)
                                                            .collect(Collectors.toSet()) // 使用Set去重
                                                            .parallelStream() // 并行流
                                                            .collect(Collectors.toMap(
                                                                Function.identity(),
                                                                roomNo -> {
                                                                    List<TUOrder> tuOrderList = ituOrderService.selectGoldenSwanRoomNuber(roomNo);
                                                                    return tuOrderList.size();
                                                                }
                                                            ));
                
                // 异步更新数据
                executorService.submit(() -> {
                    amsRooms.forEach(amsRoom -> {
                        amsRoom.setRoomPeoples(roomPeopleMap.getOrDefault(amsRoom.getRoomNo(), 0));
                        amsRoomService.updateAmsRoom(amsRoom);
                    });
                });
            }
        }
    }
    

    在这个优化版本中,首先使用并行流和Collectors.toMap()方法将所有房间号一次性查询完毕,并将结果存储在Map中。然后,在异步线程中,根据Map中的数据更新AmsRoom对象。这样做的好处是,减少了数据库查询次数,同时利用了多线程处理,提高了整体效率。

    请注意,实际应用中还需要根据具体业务场景调整线程池大小、缓存策略等参数,以达到最佳性能。此外,确保数据库和后端服务能够承受并行处理带来的并发压力。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 6月11日

悬赏问题

  • ¥15 35114 SVAC视频验签的问题
  • ¥15 impedancepy
  • ¥15 在虚拟机环境下完成以下,要求截图!
  • ¥15 求往届大挑得奖作品(ppt…)
  • ¥15 如何在vue.config.js中读取到public文件夹下window.APP_CONFIG.API_BASE_URL的值
  • ¥50 浦育平台scratch图形化编程
  • ¥20 求这个的原理图 只要原理图
  • ¥15 vue2项目中,如何配置环境,可以在打完包之后修改请求的服务器地址
  • ¥20 微信的店铺小程序如何修改背景图
  • ¥15 UE5.1局部变量对蓝图不可见