【MyBatis】从一千万记录中批量删除八百万条,耗时4m7s
批量删除主要借助了MySql的limit函数,其次用了in删除。
代码如下:
package com.hy.action;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.log4j.Logger;
import com.hy.entity.Employee;
import com.hy.mapper.EmpMapper;
public class BatchDelete1 {
private static Logger logger = Logger.getLogger(SelectById.class);
public static void main(String[] args) throws Exception{
long startTime = System.currentTimeMillis();
Reader reader=Resources.getResourceAsReader("mybatis-config.xml");
SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(reader);
reader.close();
SqlSession session=ssf.openSession();
try {
EmpMapper mapper=session.getMapper(EmpMapper.class);
int totalChanged=0;
int index=0;
while(true) {
List<Long> ids=mapper.selectIdsByDate("2018-02-02");
if(ids.size()==0) {
break;
}
int changed=mapper.deleteByIds(ids);
System.out.println("#"+index+" deleted="+changed);
session.commit();
totalChanged+=changed;
index++;
}
System.out.println("All deleted="+totalChanged);
}catch(Exception ex) {
logger.error(ex);
session.rollback();
}finally {
session.close();
long endTime = System.currentTimeMillis();
logger.info("Time elapsed:" + toDhmsStyle((endTime - startTime)/1000) + ".");
}
}
// format seconds to day hour minute seconds style
// Example 5000s will be formatted to 1h23m20s
private static String toDhmsStyle(long allSeconds) {
String DateTimes = null;
long days = allSeconds / (60 * 60 * 24);
long hours = (allSeconds % (60 * 60 * 24)) / (60 * 60);
long minutes = (allSeconds % (60 * 60)) / 60;
long seconds = allSeconds % 60;
if (days > 0) {
DateTimes = days + "d" + hours + "h" + minutes + "m" + seconds + "s";
} else if (hours > 0) {
DateTimes = hours + "h" + minutes + "m" + seconds + "s";
} else if (minutes > 0) {
DateTimes = minutes + "m" + seconds + "s";
} else {
DateTimes = seconds + "s";
}
return DateTimes;
}
}
而Mapper中的SQL语句是:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.hy.mapper.EmpMapper">
<select id="selectById" resultType="com.hy.entity.Employee">
select id,name,age,cdate as ctime from emp where id=#{id}
</select>
<insert id="batchInsert">
insert into emp(name,age,cdate)
values
<foreach collection="list" item="emp" separator=",">
(#{emp.name},#{emp.age},#{emp.ctime,jdbcType=TIMESTAMP})
</foreach>
</insert>
<insert id="singleInsert">
insert into emp(name,age,cdate)
values (#{name},#{age},#{ctime,jdbcType=TIMESTAMP})
</insert>
<select id="selectIdsByDate" resultType="java.lang.Long">
select id from emp where cdate<#{date,jdbcType=TIMESTAMP} limit 10000
</select>
<delete id="deleteByIds">
delete from emp where id in
<foreach collection="list" open="(" close=")" separator="," item="id" index="i">
#{id}
</foreach>
</delete>
</mapper>
与之对应的接口是:
package com.hy.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.hy.entity.Employee;
public interface EmpMapper {
Employee selectById(long id);
int batchInsert(List<Employee> emps);
// 用@Param标签指明和SQL的参数对应能避免出现org.apache.ibatis.binding.BindingException异常
int singleInsert(@Param("name")String name,@Param("age")int age,@Param("ctime")String ctime);
List<Long> selectIdsByDate(String date);
int deleteByIds(List<Long> ids);
}
以上粗体红字为涉及代码。
控制台输出如下:
#792 deleted=10000 #793 deleted=10000 #794 deleted=10000 #795 deleted=10000 #796 deleted=10000 #797 deleted=10000 #798 deleted=10000 #799 deleted=10000 #800 deleted=10000 #801 deleted=10000 #802 deleted=10000 #803 deleted=5199 All deleted=8035199 INFO [main] - Time elapsed:4m7s.
数据库中情况:



--END-- 2019年10月14日09:24:07
【MyBatis】从一千万记录中批量删除八百万条,耗时4m7s的更多相关文章
- 【MyBatis】【SQL】没有最快,只有更快,从一千万条记录中删除八百万条仅用1分9秒
这次直接使用delete from emp where cdate<'2018-02-02',看看究竟会发生什么. Mapper里写好SQL: <?xml version="1. ...
- 【MyBatis】【SQL】删除最快纪录诞生,从一千万条记录中删除八百万条仅用2分6秒
在 https://www.cnblogs.com/xiandedanteng/p/11669629.html 里我做个一个循环按时间查ID并删除之的程序,运行时间是4分7秒. 但是这个程序走了很多次 ...
- iOS开发:一个高仿美团的团购ipad客户端的设计和实现(功能:根据拼音进行检索并展示数据,离线缓存团购数据,浏览记录与收藏记录的批量删除等)
大致花了一个月时间,利用各种空闲时间,将这个客户端实现了,在这里主要是想记录下,设计的大体思路以及实现过程中遇到的坑...... 这个项目的github地址:https://github.com/wz ...
- SQL中批量删除被注入的恶意代码的方法
下文将为您介绍SQL中批量删除被注入的恶意代码的方法,供您参考,如果您也遇到了这样的问题,不妨一看,相信对您会有所帮助. 1,如果你的数据表很少的话,那么写几条简单的sql就搞定了 对于表中的nvch ...
- excel中批量删除公式,保留数值
excel中批量删除公式,保留数值 Sub macro1() Dim sh As Worksheet For Each sh In Sheets sh.UsedRange = sh.UsedRange ...
- VS中批量删除cs代码中的#region和#endregion
Visual Studio中如何批量删除cs代码中的#region和#endregion,不删除它们中间的代码,只删除这两个标记及标记的注解的方法.Vs中提供了很强大的文本查找与替换功能,简单的替换只 ...
- SqlServer表中两条全然同样的记录,怎样删除当中1条
描写叙述:表无主键ID,误插入两遍数据,怎样删除内容同样的记录,而仅仅留下1条. SELECT DISTINCT * INTO #temp FROM grade; DROP TABLE grade; ...
- gitlab中批量删除本地以及远程tag的操作
git 批量删除标签# 删除所有远程标签git show-ref --tag | awk '{print ":" $2}' | xargs git push origin # 删除 ...
- VS中批量删除注释
批量删除: 按ctrl+H 选上正则表达式 Find what: //.* Replace with: (空) 点replace all就行了
随机推荐
- 如何查找SAP Fiori launchpad Designer的准确路径即url地址
比如我们知道在SPRO里下面这个路径的customizing activity里打开Fiori Launchpad designer: SAP Netweaver->UI technologie ...
- Spring Cloud(二)服务提供者 Eureka + 服务消费者(rest + Ribbon)
Ribbon是什么? Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起.Ribbon客户端组件提供一系列完善的配置项如连接超时 ...
- MySQL8.0 caching_sha2_password报错问题
在bin目录下执行mysql -uroot -p123456 登录后执行: use mysql; select host, user, plugin from user; 打印: +--------- ...
- 【python+beautifulsoup4】Python中安装bs4后,pycharm报错ModuleNotFoundError: No module named 'bs4'
本文主要分享关于在对应python版本中安装beautifulsoup之后,在代码执行时还会提示“No module named 'bs4'”的问题. 安装beautifsoup4 在命令窗口执行 p ...
- linux终端c语言改变输出字体颜色
Linux下C改变输出字体颜色 例: #include int main() { printf("\033[31mThis is RED.\n\033[0m"); return 0 ...
- Django基础(一):基础引用
Web框架本质 我们可以这样理解:所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端. 这样我们就可以自己实现Web框架了. 半成品自定义web框架 impor ...
- web开发:清浮动
一.display总结 二.overflow 三.浮动布局 四.清浮动 五.清浮动的方式 一.display总结 <!DOCTYPE html> <html> <head ...
- java—多线程—notify/notifyAll
notify应该使用在,只有两个线程在调用类中的两个方法,并在两个方法中进行互斥操作? 博客:Java多线程学习之wait.notify/notifyAll 详解 未完待续……
- MyBatis中#{}和${}的不同和${}的妙用(转)
突然意识到sql语句的独特语义要和代码分离,我们就不能够在代码中写sql语句!!比如我要用${}在MyBatis的sql中拼接排序类型的时候,我就不能够在Java代码中直接写参数字符串为Ord ...
- Codeforces Round #455 (Div. 2) 909E. Coprocessor
题 OvO http://codeforces.com/contest/909/problem/E CF455 div2 E CF 909E 解 类似于拓扑排序地进行贪心, 对于 Ei=0 并且入度为 ...