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

推荐订阅源

G
Google Developers Blog
Google DeepMind News
Google DeepMind News
Hugging Face - Blog
Hugging Face - Blog
D
Docker
F
Fortinet All Blogs
博客园 - 三生石上(FineUI控件)
Project Zero
Project Zero
Engineering at Meta
Engineering at Meta
J
Java Code Geeks
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Simon Willison's Weblog
Simon Willison's Weblog
S
Security Affairs
NISL@THU
NISL@THU
T
Tor Project blog
A
About on SuperTechFans
宝玉的分享
宝玉的分享
腾讯CDC
S
Schneier on Security
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
P
Privacy & Cybersecurity Law Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Stack Overflow Blog
Stack Overflow Blog
P
Privacy International News Feed
雷峰网
雷峰网
C
Cyber Attacks, Cyber Crime and Cyber Security
Vercel News
Vercel News
Cisco Talos Blog
Cisco Talos Blog
D
DataBreaches.Net
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Google Online Security Blog
Google Online Security Blog
Recorded Future
Recorded Future
L
LINUX DO - 热门话题
Microsoft Security Blog
Microsoft Security Blog
Latest news
Latest news
C
Check Point Blog
有赞技术团队
有赞技术团队
T
The Exploit Database - CXSecurity.com
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
云风的 BLOG
云风的 BLOG
SecWiki News
SecWiki News
Application and Cybersecurity Blog
Application and Cybersecurity Blog
爱范儿
爱范儿
月光博客
月光博客
V
Vulnerabilities – Threatpost
T
Threat Research - Cisco Blogs
P
Palo Alto Networks Blog
T
The Blog of Author Tim Ferriss
C
Cisco Blogs
Webroot Blog
Webroot Blog
S
Security @ Cisco Blogs

博客园 - 江城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