惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

W
WeLiveSecurity
博客园 - 【当耐特】
Microsoft Azure Blog
Microsoft Azure Blog
WordPress大学
WordPress大学
Stack Overflow Blog
Stack Overflow Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
IT之家
IT之家
Cloudbric
Cloudbric
The Register - Security
The Register - Security
小众软件
小众软件
PCI Perspectives
PCI Perspectives
G
Google Developers Blog
AI
AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Google DeepMind News
Google DeepMind News
Google DeepMind News
Google DeepMind News
宝玉的分享
宝玉的分享
Recent Commits to openclaw:main
Recent Commits to openclaw:main
量子位
TaoSecurity Blog
TaoSecurity Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
F
Full Disclosure
N
Netflix TechBlog - Medium
博客园_首页
Last Week in AI
Last Week in AI
A
Arctic Wolf
B
Blog RSS Feed
J
Java Code Geeks
C
Cybersecurity and Infrastructure Security Agency CISA
I
InfoQ
aimingoo的专栏
aimingoo的专栏
云风的 BLOG
云风的 BLOG
NISL@THU
NISL@THU
MyScale Blog
MyScale Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Jina AI
Jina AI
有赞技术团队
有赞技术团队
S
Schneier on Security
L
Lohrmann on Cybersecurity
P
Privacy & Cybersecurity Law Blog
T
Threat Research - Cisco Blogs
P
Palo Alto Networks Blog
S
Security @ Cisco Blogs
Security Archives - TechRepublic
Security Archives - TechRepublic
Security Latest
Security Latest
Vercel News
Vercel News
博客园 - 司徒正美
Webroot Blog
Webroot Blog
Hacker News: Ask HN
Hacker News: Ask HN
A
About on SuperTechFans

博客园 - 江城2211

大数值的精度与格式化显示问题 【知识总结】数据库的事务、并发与锁管理 基于数据源连接,动态构造JPA上下文EntityManager 【转载】使用了HTTPS为啥还要接口数据加密? RSA加密算法,加解密、签名示例 国密SM2算法,加密、签名示例 【知识总结】JVM线程堆栈中的基础概念解读 【问题记录】JVM进程崩溃(hs_err_pid.log致命错误日志) [问题记录】存在视图依赖的数据表,DDL修改字段比如做扩容等注意事项 【问题总结】Garmin路线无法同步和地图坐标偏移的解决办法 【工具推荐】磁盘IO检测工具之Diskspd 【编码技巧】总结一个稳定而高效的方法,将二维关系数据转换为树形结构 【编程技巧】SQL脚本快速生成随机测试数据 【编程技巧】结合JPA通用分页与排序技术,支持百万级以上数据的DML批量处理方案 【使用技巧】CodeDecom.exe批量反编译JAR包+Beyond Compare对比 【问题记录】Cause: java.sql.SQLRecoverableException: No more data to read from socket JDBC与各数据库产品连接的驱动及URL示例 【问题记录】使用PowerDesigner连接数据库并反向工程生成所有表及关系 使用tcpdump抓取网络包,在wareshark查看对应请求及响应的原始报文
【编码技巧】批量校验或处理关联引用数据的优化总结
江城2211 · 2024-09-05 · via 博客园 - 江城2211

问题描述:

       之前有信创项目反馈了一个批量导入的性能问题,400条数据需要3分钟,5000条需要20分钟以上,系统初始需要导入的各类数据有上百万。

原因分析:

       联系项目导入20~30条数据,并启用程序跟踪收集性能数据发现,有大量对字典表的SQL查询。

       与功能开发同事沟通确认,该SQL是导入模板中有几个关联字段,用户录入的是编码或名称,后台需要根据编号或名称查询对应的Id值,目前是简单粗暴的循环处理。

       原因倒是很清楚,如果只是为了减少对关联字段的查询次数,可以直接一次将关联数据全部加载做缓存处理,前提是关联数据的全量数据不能太大,否则容易导致OMM。

优化方案:

       按列汇总所有数据并去重,建立当前关联列数据的Map<name, id>缓存,分批次去DB检索数据,并存入Map缓存:

       1、取出一个批次的数据 names(n=names.size(),  n<=500)

       2、检查Map缓存中是否已存在

            2.1、如果Map已缓存,就根据map直接标记检查结果,并从names移除该数据

            2.2、如果n<300,则再次执行第1步骤,直至n=300或当前列所有数据均已被处理

       3、select id, name from helpdata where name in (names);

       4、将name->id作为键值对加入map

       5、将names 与 nameList的差集,按 name –> null 加入map

       6、重新执行第1步骤,直至当前列所有数据被处理完毕

       此方案基于一个这样的事实:一次导入或处理的数据是相对有限的(一般而言,<=10w最多也不会超过50w,再多也是分成多个批次处理),而这一个批次中某列的关联数据有可能是百万乃至千万的量级。

       如果按行循环处理,需要循环rowNum * columnNum次,以10w行、20列引用字段为例,需要执行200w次SQL查询请求;

       如果一次将关联帮助数据全部加载至内存,则对于项目、往来等可能存在很大数据量的场景,会直接导致应用OOM;

       按照本方案,理论上最坏的情况也仅执行4k次SQL查询请求(10w行、20列),而真实场景是一次处理的数据中关联列字段值重复概率非常高,实际执行的SQL请求和内存占用远低于理论的最大值。

效果验证:

       产品功能按此方案优化,部署到项目后反馈良好:内存占用稳定,1k数据(2个关联列)处理响应时间从之前的3分钟提升至10秒左右。

       image