【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就行了
随机推荐
- sql server 语句书写注意事项
1 Between在某些时候比IN 2 在必要是对全局或者局部临时表创建索引,有时能够提高速度,但不是一定会这样,因为索引也耗费大量的资源.他的创建同是实际表一样 3 尽量少用视图,它的效率低.对视 ...
- 复选框已经有checked,但是页面没有选中效果(解决)
原代码: $("#checked").click(function(){ $(".input[name="checked"]").attr( ...
- Webstorm2017.3.3软件的安装使用
下载 ▶进入jetbrains的官方网站点击download,即下载开始.官方网站链接:http://www.jetbrains.com/webstorm/ 安装 ▶双击刚下载完成的.exe文件开始进 ...
- 12.Show Profile
1.是什么: 是mysql提供可以用来分析当前会话中语句执行的资源消耗情况,可以用于SQL的调优的测量 show profile 查询SQL在MySQL服务器里面的执行细节和生命周期情况 2.默认情况 ...
- 【Java并发】线程通信
一.概述 1.1 什么是多线程之间通讯? 1.2 案例 代码实现 解决线程安全问题 二.等待通知机制 2.1 示例 2.2 wait与sleep区别 三.Lock锁 3.1 概述 3.2 等待/通知机 ...
- Win10系统升级更新方式将会更智能
使用Win10系统的你肯定遇到过在工作时开始自动更新而不得不搁置工作的情况,想必你也已经被Win10系统的自动更新折磨不已,不过这种情况将会马上得到改观. 微软现在已经开始寻找更智能的版本升级更新方式 ...
- TensorFlow 拾遗
1..Here None in placeholder means that a dimension can be of any length. 2.. 3.. 4.. 5.. tf.mul ...
- linux下动态库中的soname
soname( Short for shared object name) 其是应用程序加载dll 时候,其寻找共享库用的文件名.其格式为 lib + math+.so + ( major versi ...
- onpageshow、onpagehide、onload、onunload
onpageshow :在用户浏览网页时触发, 在页面从浏览器缓存中读取时也触发 通过event.persisted 来判断, 如果页面从浏览器的缓存中读取该属性返回 ture,否则返回 false ...
- 单独使用ibatis做事物控制。
当项目中,只使用到了ibatis而没有使用spring来作为事物控制的时候,可以这样写: try { Reader reader = Resources.getResourceAsReader(&qu ...