sqlldr导入数据比较慢(sqlldr导入导出)

sqlldr导入数据比较慢(sqlldr导入导出)文章目录 积木报表 Excel 数据量大导出慢导不出问题 大量数据导不出问题优化方案和分析解决思路 优化前一万多导出失败 优化后支持百万级跨库表导出 已开源 反馈官方进度 跟官方反馈这个方案后 官方直接优化了但是把原本这个免费的大数据导出做成了收费功能 绝了 我直接把我方案开源 优化结果 需求背景和解决方案的思考 解决方案 流程描述 关键代码 引入 easy excel 新建数据库表

大家好,我是讯享网,很高兴认识大家。



文章目录

  • 积木报表Excel数据量大导出慢导不出问题、大量数据导不出问题优化方案和分析解决思路(优化前一万多导出失败,优化后支持百万级跨库表导出,已开源)
  • 反馈官方进度
  • 跟官方反馈这个方案后,官方直接优化了但是把原本这个免费的大数据导出做成了收费功能!绝了,我直接把我方案开源
  • 优化结果
  • 需求背景和解决方案的思考
  • 解决方案
  • 流程描述:
  • 关键代码
  • 引入easy excel
  • 新建数据库表
  • 识别所需注解、基类
  • 下载中心服务(报表下载的导出任务)
  • 数据跨库获取工具
  • 拦截切面
  • 报表下载任务处理事件
  • 透传信息
  • 给前端暴露接口

反馈后看到后续的版本里有说升级了这个,于是我升级了包测试,直接这个功能需要企业版才给用了,寄,不如直接用下载中心模式得了,有空把这个下载中心的代码抽出来封装好开源放github 0

下载中心这个能力抽出来脱敏成开源项目已准备的差不多了,准备好后更新文章,帮忙点star支持开源
地址:https://github.com/HumorChen/JimuExportDataExtension

一千万条数据mysql导入大概多久_excel
讯享网

一千万条数据mysql导入大概多久_报表导出_02

一千万条数据mysql导入大概多久_excel_03

一千万条数据mysql导入大概多久_报表导出_04

一千万条数据mysql导入大概多久_报表导出_05

一千万条数据mysql导入大概多久_excel_06

一千万条数据mysql导入大概多久_excel_07

详细讲了需求来由、解决历程的思考心路历程,有点长,想学习解决思路的可认真阅读,只需要解决方案的可以不看。我这正是因为当前项目组还没有专门做数据仓库的人,先用的积木这样的报表来做的。数据量大之后性能看着很心累,数据量大建议招专业的做数仓的。
项目组的数据报表、导出最开始的技术人员选型的是开源的积木报表(积木报表GitHub地址(5.4K star)),后续积木闭源了。在后续数据量增加后,积木报表经常性导出失败,运营同学反馈多次,于是优化报表的重担交给了我。
一期我先优化了SQL、涉及表的索引,取消走SQL join 一二十张表的方案,改为API代码分页实现查询。上线后效果仍旧不行,于是继续深入分析性能瓶颈,观察链路跟踪后发现,在导出时内存和CPU都飙升,甚至内存会被拉爆。
我看了下实际SQL执行时间其实相对于整个导出过程并没有很长,在500ms左右一个分页(5000条一个页,减少页到1000,2000未发现明显性能提升),在整个导出操作流程中,我通过抓包和链路跟踪查看,链路是导出按钮调用了积木的一个exportAllExcelStream接口,然后积木内部代码又去调用我配置的表数据源接口地址,将分页和查询条件拿去调我们项目接口获取数据,并导出为excel写入导出请求的响应流里,那既然我们获取数据的接口耗时占整个导出操作的占比低,其实性能瓶颈在积木框架内部。
于是我打开积木的代码一看,好家伙,都是abcdefg这样的命名,做过代码混淆加密的就一眼看得出,变量名被重命名混淆过了,甚至连积木导出接口的字符串都搜索不到没法找到入口,看来接口字符串都做了隐藏,于是我怀疑是excel导出大量数据有性能问题,我看了下积木依赖的pom文件里引入的是org.apache.poi,我去百度搜索了相关文章后,看到了其他博主说Apache POI导出有性能问题,性能低下,占用过多的内存,数据量大的时候特别明显,推荐使用阿里巴巴的EasyExcel来导出表格,只有十分之一的消耗。
于是收集完情况后,目前摆在眼前的两个痛点,第一个是导出慢会慢到网关直接504返回超时(一个接口调用几分钟以上),第二个是积木报表自身用了POI导出很慢,和领导讨论了一下,超时问题可以走异步实现解决,写一个导出下载中心,导出操作接口快速返回一个空的(注解+AOP切面实现拦截),然后异步去再次调用积木导出接口,并设置上请求头,方便拦截接口导出的切面识别到这个是异步执行,就返回实际数据不要返回空数据,这样就不会接口超时了,这个方案我先实现了下确实可行。
第二个问题就是导出慢的解决,由于闭源还有代码混淆加密操作,无法二开代码,因此要想解决POI这个问题你就需要自己实现导出,第一个想到的操作是直接在积木报表的页面加个快速导出按钮,可页面代码是积木自己生成的,不方便植入,第二个思路是,识别积木的导出操作,因为积木导出的时候还是要来我们接口这获取数据的,获取的时候带了分页信息,我们根据每页数据和配置的积木导出时每页数据条数这个配置对比就能识别到是不是导出操作,平时查看是10条每页,导出的时候会变5000条一页,很好区分,但区分完了,怎么实现导出操作呢?报表都是在积木的报表设计里用鼠标点点点的UI操作设计的,你自己接口怎么知道表头、数据源、表名、哪个账户导出的?
带着这些问题我深入查看了积木的数据库表,你积木能读取我就能读取,我看看你到底把这些关键信息存储在哪里了,翻开数据表里可以看到的,确实把表格的字段、宽度、样式、表格ID之类的信息都在Mysql里存着呢,那我只需要写一个解析这些数据的服务就可以像积木一样导出了。
方案思路可行性得到确认,那我就开始将复杂任务流程关键问题拆解并解决:
第一个是积木点击导出时的参数信息要完整拿到并保存到我们自己设计的导出任务里
(走积木自定义header预留的钩子实现透传请求数据)
第二个是要能正确读取我们人工在积木报表里配置的数据源API、表头名、表头字段等信息
(自行配置一个示范表并看数据库数据怎么存的,写代码解析这个数据结构并返回我们标准化的解析方法)
第三个是要自行实现调用数据源AP时积木的那次导出操作被拦截返回空数据,我们自己的导出正常导出数据
(新加注解,拦截注解的API,识别是否为积木导出操作,是则拦截,生成导出任务,返回空数据集合,否则直接执行原接口逻辑返回正常数据)
第四个是正确根据积木里的表头字段等信息使用EasyExcel生成表格并将表格上传到OSS,中间不建议产生机器上的物理文件(使用二进制流保存)
(写一个指定接口分页导出工具,按分页不断调用数据获取接口获得元数据,利用前面获得的表头字段进行解析生成EasyExcel导出数据时需要的结构体,最后使用EasyExcel将数据导出为excel文件的二进制流)

一千万条数据mysql导入大概多久_一千万条数据mysql导入大概多久_08

流程描述:

识别并拦截积木导出操作,透传导出时参数生成自己设计的导出任务,异步执行导出任务(自行实现积木导出的逻辑),并使用高性能的阿里巴巴开源的EasyExcel工具,最后将EasyExcel导出的表格文件上传到OSS变为表格URL(记得做安全防护,避免表格泄漏)

关键代码

大部分代码是不需要你改的,你可以根据自己项目结合使用,例如OSS上传的地方改为你自己的。后面的代码有点长~需要的人依次把代码弄进自己项目。

引入easy excel
新建数据库表

下载任务

使用mabatis plus code generator生成service、mapper等文件

识别所需注解、基类

数据获取api所调用服务上方法上标注的注解

示范给数据接口调用的服务加注解

参数基类

结果基类

下载中心服务(报表下载的导出任务)

实现类

数据跨库获取工具

服务接口

服务实现

拦截切面
报表下载任务处理事件

暂时由于导出项目只部署一个实例,导出任务使用的是spring 本地event来异步处理的,你可以使用MQ、调度来执行掉任务,可以参考我这个
上传华为云OSS的部分你替换为你的OSS上传操作,这个地方我是复用项目里已有的存储上传服务
里面的异步线程池、环境工具类、积木导出每页大小要设置自己的

处理器

透传信息

主要是在这个customApiHeader() 方法里DownloadCenterUtil.copyDownloadCenterHeader(request, header);自定义获取数据请求的header这,读取这次积木导出请求的参数信息,写到获取数据请求的header里去

下载中心工具类

异步线程池

给前端暴露接口

DynamicColumnEasyExcelUtil 动态字段EasyExcel工具

小讯
上一篇 2025-06-10 14:46
下一篇 2025-04-19 10:58

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/203554.html