首页 > 其他分享 >百万级以上的DML批量处理方案

百万级以上的DML批量处理方案

时间:2024-06-22 16:53:26浏览次数:13  
标签:String 批量 DML list value parentId where id 百万

百万级以上的大数据量的批量更新或删除,如果直接采用传统update、delete等DML,在高并发的生产系统有可能导致数据库宕机乃至触发数据库bug导致数据不一致等问题。

考虑了一下可行的解决方案:

方案一,只保留少量数据的删除场景,可以先将保留的数据查出并插入中间表,truncate原表然后再将中间表插入回原表

方案描述已经很明确了,只能适用于非常特定的场景,保留的数据量也很多,或者是数据的更新场景都没法使用

方案二,最朴素的想法,两层循环:外循环每次查询1w条,内循环每次删除1k条delete from t where id in (0…999) 或 delete from t where id= ?1  or  id = ?2 …..

此方案的弊端是每批次操作的数据量太少、应用与DB的交互次数太多,并且根据实际验证SQL脚本太长、in或or的数据量超过500+等情况,在部分数据库上的性能急剧下降。

方案四,采用各数据库的大批量删除方案

此方案的问题是各数据库的方言差异很大,对支持多种数据库的通用产品来说,需要逐个适配。

Oracle:
     delete from products where update_time < to_timestamp(‘2010-01-01 00:00:00’, ‘yyyy-mm-dd hh24:mi:ss’) and rownum <=100000;

SqlServer:
     DELETE TOP (100000)     FROM Purchasing.PurchaseOrderDetail     WHERE DueDate < '20020701';

MySQL:
   delete from t where DueDate < '20020701' limit = 100000;

PostgreSQL:
   delete from t where id in (select id from t where DueDate < '20020701'  limit 100000);


方案四,即另一种方案实践:排序字段分页查询与DML方案+JPA屏蔽数据库差异+数据库索引与批量优势

批量删除--Service层示例代码如下:

// 批量删除
String parentId = "50d29225-7fc1-4a5d-a77a-d89e0a315158";
Sort sort = Sort.by(Sort.Direction.ASC, "Id");
Pageable pageable = PageRequest.of(10000, 10, sort);
List list = null;
do {
     list = repository.findByParentId(parentId, pageable);
     if (list == null || list.size() < 10) {  // 不足10w数据,直接删除
         repository.deleteAllByParentId(parentId);
     }
     else {  // 超过10w数据,仅删除前10w数据
         repository.deleteAllByParentIdAndLessThanId(parentId, list.get(list.size()));
     }
} while (list != null && list.size() >= 10);


批量删除--Repository层示例代码如下:
@Transactional
@Modifying
@Query(value = "value=”delete from entityName where parentId = ?1")
void deleteAllByParentId(String parentId);


@Transactional
@Modifying
@Query(value = "value=”delete from entityName where parentId = ?1 and id <= ?2")
void deleteAllByParentIdAndLessThanId(String parentId, String id);


@Query(value = "value=”select * from entityName where parentId = ?1")
List queryByParentId(String parentId, Pageable pageable);




批量更新--Service层示例代码:

String parentId = "50d29225-7fc1-4a5d-a77a-d89e0a315158";
Sort sort = Sort.by(Sort.Direction.ASC, "Id");
Pageable pageable = PageRequest.of(10000, 10, sort);
List list = null;

String preid = “”;
do {
    list = repository.queryByParentIdAndGreaterThanId(parentId, preid, pageable);

   
     if (list == null || list.size() < 10) {  // 不足10w数据,直接删除
        repository.updateByParentIdAndBetweenId(parentId, preid, null);
     }
    else {  // 超过10w数据,仅删除前10w数据
        repository.updateByParentIdAndBetweenId(parentId, preid, list.get(list.size()));

        preid = list.get(list.size());
     }
} while (list != null && list.size() >= 10);


批量更新场景,Repository层示例代码:

@Transactional
@Modifying
@Query(value = "value=”update entityName set qty = qty+1 where parentId = ?1 and id > ?2 and (id <= ?3 or  ?3 is null)")
void updateByParentIdAndBetweenId(String parentId, String preId, String nextId);

// 批量更新场景,查询时需要排除已经处理过的数据
@Query(value = "value=”select * from entityName where parentId = ?1 and id > ?2)
List queryByParentIdAndGreaterThanId(String parentId, String id, Pageable pageable);



参考资料:


https://blog.csdn.net/qq_44112474/article/details/109174901 

https://blog.csdn.net/chengyj0505/article/details/128358817 

https://blog.csdn.net/itmyhome1990/article/details/82114519 

https://www.cnblogs.com/ashbur/p/12020584.html 

https://www.cnblogs.com/kerrycode/p/12448322.html

https://blog.csdn.net/caicaimaomao/article/details/123910749

https://blog.csdn.net/Hehuyi_In/article/details/107775528

标签:String,批量,DML,list,value,parentId,where,id,百万
From: https://www.cnblogs.com/zhaoguan_wang/p/18262497

相关文章

  • 如何使用SQL工具批量执行SQL文件?(以MySQL和SQLynx为例)
    目录1.配置MySQL数据源2.打开SQL文件3.执行SQL文件4.检查执行结果5.SQL文件示例6.注意事项7.总结在现代数据库管理和操作中,批量执行SQL文件在MySQL中显现出其巨大的价值和不可替代的作用。通过将多个SQL语句集成在一个文件中进行批量处理,数据库管理......
  • 2024版蒲公英平台采集软件,批量爬取小红书优质博主!
    目录一、背景介绍1.0爬取目标1.1演示视频1.2软件说明二、代码讲解2.0关于接口2.1爬虫采集模块2.2cookie获取2.3软件界面模块2.4日志模块三、转载声明一、背景介绍1.0爬取目标众所周知,蒲公英是小红书推出的优质创作者商业合作服务平台,致力于为品牌和博主提供内容合作......
  • 如何给excel文件批量加密?给excel文件批量加密的四个方法
    在Excel当中我们如何对表格文档进行加密,其实在Excel表格当中对文档加密的方式一共有两种,一种是密码加密;另一种是账号加密。那么今天我们就先来讲讲密码加密是怎么一回事儿,之后再给大家讲解一下账号加密的操作方式。对于密码加密,在平时的Excel办公当中,我们的文档不想让别人查看......
  • 批量归一化教学文章概要
    由于篇幅限制,我将提供一篇简洁的教学文章概要,包括关键概念和示例代码,来介绍批量归一化(BatchNormalization)。批量归一化教学文章概要引言深度学习模型在训练过程中常常面临梯度消失或爆炸的问题,这会导致模型训练缓慢或不稳定。批量归一化(BatchNormalization)是一种有效的......
  • Python批量保存Excel文件中的图表为图片
    Excel工作簿作为一款功能强大的数据处理与分析工具,被广泛应用于各种领域,不仅能够方便地组织和计算数据,还支持用户创建丰富多彩的图表,直观展示数据背后的洞察与趋势。然而,在报告编制、网页内容制作或分享数据分析成果时,直接嵌入整个Excel文件往往不够便捷,且可能受限于接收者......
  • 文件重命名 一键批量重命名10万+文件 简单效率高!
    单个文件重命名大家应该都会操作,但是有一些人由于工作的场景等的情况,需要做大量的文件重命名,比如影楼、电商、仓库管理、图片处理等各种行业,都经常需要把一批文件,按一定的格式和规律给文件重命名。 一、批量文件重命名,我们需要“芝麻文件重命名”(https://filetool.zhimas......
  • Linux PXE高效批量装机
    部署PXE远程安装服务在大规模的Linux应用环境中,如Web群集、分布式计算等,服务器往往并不配备光驱设备,在这种情况下,如何为数十乃至上百台服务器裸机快速安装系统呢?传统的USB光驱、移动硬盘等安装方法显然已经难以满足需求。本章将学习基于PXE(PrebooteXecutionEnvironm......
  • mybatis批量更新(where的条件越少,最好是主键,效率越高)
    <updateid="updateBatch"databaseId="sqlserver">updateT_RISK_TASK_SERVICE<trimprefix="set"suffixOverrides=","><trimprefix="TASK_REALITY_START_TIME=case......
  • 06 PXE高效批量网络装机
    1、部署PXE远程安装服务在大规模的Linux应用环境中(如Web集群、分布式计算等),服务器往往并不配装备光驱设备。在这种情况下,传统的USB光驱、移动硬盘等安装方法显然已经难以满足需求。那么如何为数十台服务器裸机快速安装系统呢?基于PXE技术的网络装机方法,并结合Kickstart配置......
  • PXE高效批量网络装机(补充) 实验部分
    然后把防火墙、安全机制全都给关闭掉,不要让它们干扰后续的实验:然后安装那几个需要用到的软件包:如果重启了系统vsftpd是不能自动启动起来的,如果想让该服务每次开机都自动的启动起来,可以执行下图中的命令:注:在dhcp的配置文件里面需要指定一些TFTP的相关数据然后保......