导出任务耗时如何优化

简介: 大量数据的导入导出时,请求一定非常耗时,页面一定会不停转圈圈,不可能让用户一直停留在这个页面转圈圈,这样并不友好。比较好的方式就事通过异步的方式,先提交任务,然后通过线程的处理数据。一次性如果导出大量数据时,需要批量查询结果到处。

大量数据的导入导出时,请求一定非常耗时,页面一定会不停转圈圈,不可能让用户一直停留在这个页面转圈圈,这样并不友好。

比较好的方式就事通过异步的方式,先提交任务,然后通过线程的处理数据。一次性如果导出大量数据时,需要批量查询结果到处。

导出功能设计:

前端页面设计如下: 新增 导出按钮 和导出记录按钮 导出记录页面字段如下: 批次号  时间  导出URL  操作(导出) 后端表结构

sql

代码解读

复制代码

create table export_record(
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
 `batch_no` varchar(32)  DEFAULT NULL COMMENT '导入批次号',
 `export_type` varchar(3) DEFAULT NULL COMMENT '类型(1:订单导出)',
  `export_url` varchar(300) DEFAULT NULL COMMENT 'url',
 `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建日期',
  `create_code` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人代码',
  `create_name` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人名称',
  `last_update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
  `last_update_code` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '最后更新人',
  `last_update_name` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '最后更新人',
   PRIMARY KEY (`id`),
   KEY `index_import_record` (`batch_no`) USING BTREE
)ENGINE=InnoDB  COMMENT='导出记录';

后端功能逻辑: 将导出的数据生成excel文件,并上传到服务器中,上传的文件生产的url保存记录,供前端页面下载excel文件

导入功能设计

前端页面设计如下:导入记录页面字段如下: 批次号  时间  总条数 成功条数 操作

sql

代码解读

复制代码

create table import_record (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
 `batch_no` varchar(32)  DEFAULT NULL COMMENT '导入批次号',
 `export_type` varchar(3) DEFAULT NULL COMMENT '类型(1:订单导出)',
  `total_num` int DEFAULT 0 COMMENT '总数量',
  `success_num` int DEFAULT 0 COMMENT '成功数量',
 `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建日期',
  `create_code` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人代码',
  `create_name` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人名称',
  `last_update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
  `last_update_code` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '最后更新人',
  `last_update_name` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '最后更新人',
   PRIMARY KEY (`id`),
   KEY `index_import_record` (`batch_no`) USING BTREE
)ENGINE=InnoDB  COMMENT='导入记录';


create table import_record (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
 `batch_no` varchar(32)  DEFAULT NULL COMMENT '导入批次号',
 `export_type` varchar(3) DEFAULT NULL COMMENT '类型(1:订单导出)',
  `total_num` int DEFAULT 0 COMMENT '总数量',
  `success_num` int DEFAULT 0 COMMENT '成功数量',
 `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建日期',
  `create_code` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人代码',
  `create_name` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人名称',
  `last_update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
  `last_update_code` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '最后更新人',
  `last_update_name` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '最后更新人',
   PRIMARY KEY (`id`),
   KEY `index_import_record` (`batch_no`) USING BTREE
)ENGINE=InnoDB  COMMENT='导入记录';

导入逻辑: 对导入的excel文件进行解析,并保存解析出来的数据。

大量数据查询拆分成批量任务查询

导出数据可能会导出大量数据,通常情况下,一次性查询大量数据导致负载压力的原因是在一次查询中同时检索了太多数据,并在内存中进行处理,这会占用大量系统资源,造成系统响应变慢和崩溃等问题。

mysql会将检索出来的数据都缓存到内存,一次性返回到服务端,这样会占用大量的内存资源,导致内存不足,从而影响系统运行稳定性。

解决的方式是批次处理,如分页查询数据,从而减少mysql查询占用的内存。

分页查询工具如下:

java

代码解读

复制代码

@CustomLog
public class PageBigDataUtil {

    /**
     * @param queryParam 查询条件
     * @param function 分页查询
     * @return
     */
    public static <T> List<T> pageBigData(T queryParam, Function<PageQueryBean<T>, PageQueryBean<T>> function) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        List<T> results = new ArrayList<>();
        int size = 500;
        int current = 1;
        for (; ; ) {
            PageQueryBean<T> pageParam = new PageQueryBean<>();
            SimplePage<T> simplePage = new SimplePage<>();
            simplePage.setPageSize(size);
            simplePage.setPageNum(current);
            pageParam.setPage(simplePage);
            pageParam.setParameter(queryParam);
            PageQueryBean<T> result = function.apply(pageParam);
            logger.keyword("分页批次任务").info("--------导入开始,本批次共:{} 轮,当前第{}轮", result.getPage().getPages(), current);
            if (DataUtil.isEmpty(result)) {
                break;
            }
            results.addAll(result.getPage().getList());
            if ((long) size * current >= result.getPage().getTotal()) {
                break;
            }
            current++;
        }
        stopWatch.stop();
        logger.info("批次任务已结束,分页批次任务:{},获取总记录数:{},总耗时:{}秒", current, results.size(), stopWatch.getTotalTimeSeconds());
        return results;
    }

    /**
     *
     * @param queryParam 查询条件
     * @param function 分页查询
     * @param consumer 批次消费
     * @param <T>
     */
    public static <T> void handleBigData(T queryParam, Function<PageQueryBean<T>, PageQueryBean<T>> function, Consumer<List<T>> consumer) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();

        int size = 500;
        int current = 1;
        for (; ; ) {
            PageQueryBean<T> pageParam = new PageQueryBean<>();
            SimplePage<T> simplePage = new SimplePage<>();
            simplePage.setPageSize(size);
            simplePage.setPageNum(current);
            pageParam.setPage(simplePage);
            pageParam.setParameter(queryParam);
            PageQueryBean<T> result = function.apply(pageParam);
            if (DataUtil.isEmpty(result)) {
                break;
            }
            // 业务处理
            consumer.accept(result.getPage().getList());
            logger.keyword("分页批次任务").info("--------导入开始,本批次共:{} 轮,当前第{}轮", result.getPage().getPages(), current);
            if ((long) size * current >= result.getPage().getTotal()) {
                break;
            }
            current++;
        }
        stopWatch.stop();
        logger.info("批次任务已结束,总耗时:{}秒", stopWatch.getTotalTimeSeconds());
    }
}



相关文章
|
存储 安全 算法
MySQL 数据库支持国密算法
数据库加密,作为杀手锏,是数据库底线防守的秘密武器,通过在数据库存储层进行数据加密处理,达到即使数据被黑客盗取也无法解密的效果,从根源上解决数据泄露问题。 近年,市场对于数据库加密产品的需求呈上升趋势,但由于技术门槛极高,国内真正能够提供此类产品的企业本就寥寥无几,尤其针对全球份额排名第二的MySQL数据库,能够对其支持的加密产品一直没有出现。 不同于传统的视图+触发器模式的透明加密方式,本文所提MySQL国密加密产品采用数据库引擎代码改造技术,真正实现数据在存储层的加、解密功能,避免以往加密过程中,数据库文件导入导出的繁琐方法,最大程度减少性能损失。 产品是为用户需求而生,而我们要做的
1978 0
|
JavaScript Java 关系型数据库
Springboot+vue的应急救援物资管理系统,Javaee项目,springboot vue前后端分离项目。
Springboot+vue的应急救援物资管理系统,Javaee项目,springboot vue前后端分离项目。
|
编解码 NoSQL Java
使用Spring Boot + Redis 队列实现视频文件上传及FFmpeg转码的技术分享
【8月更文挑战第30天】在当前的互联网应用中,视频内容的处理与分发已成为不可或缺的一部分。对于视频平台而言,高效、稳定地处理用户上传的视频文件,并对其进行转码以适应不同设备的播放需求,是提升用户体验的关键。本文将围绕使用Spring Boot结合Redis队列技术来实现视频文件上传及FFmpeg转码的过程,分享一系列技术干货。
907 4
|
机器学习/深度学习 数据采集 人工智能
文档智能和检索增强生成(RAG)——构建LLM知识库
本次体验活动聚焦于文档智能与检索增强生成(RAG)结合构建的LLM知识库,重点测试了文档内容清洗、向量化、问答召回及Prompt提供上下文信息的能力。结果显示,系统在自动化处理、处理效率和准确性方面表现出色,但在特定行业术语识别、自定义向量化选项、复杂问题处理和Prompt模板丰富度等方面仍有提升空间。
547 0
|
12月前
|
机器学习/深度学习 编解码 算法
《多模态数据信息提取解决方案的体验与部署》
《多模态数据信息提取》解决方案提供了一站式的文本、图像和音频数据处理平台,通过先进算法实现关键信息的高效提取。函数应用模板简化了部署流程,标准化接口和自动化配置降低了技术门槛。然而,参数设置、错误处理和文档说明等方面存在细节问题,需进一步优化以提高用户体验和部署效率。改进措施包括加强参数说明、完善错误处理机制及优化文档,推动多模态数据处理技术的发展。
321 23
|
Linux Windows
端口占用的解决方法
本文介绍了在Windows和Linux系统中解决端口占用问题的方法,包括使用`netstat`命令查看端口占用情况、`tasklist`命令查找对应进程,以及使用`taskkill`命令终止进程,在Linux系统中则使用`netstat`或`lsof`命令查找占用端口的进程,并用`kill`命令结束进程。
|
XML Java 测试技术
testNG框架从入门到精通
testNG框架从入门到精通
testNG框架从入门到精通
|
小程序 JavaScript 开发工具
微信小程序开发工具的使用,各个配置文件详解,小程序开发快速入门(一)
微信小程序开发工具的使用,各个配置文件详解,小程序开发快速入门(一)
986 1
|
Linux
如何在Linux中删除目录的所有文件?
如何在Linux中删除目录的所有文件?
1536 1
如何在Linux中删除目录的所有文件?
|
存储 数据处理 数据格式
Python中导入Excel数据:全面解析与实践
Python中导入Excel数据:全面解析与实践
721 0