zoukankan      html  css  js  c++  java
  • 【MyBatis】【SQL】没有最快,只有更快,从一千万条记录中删除八百万条仅用1分9秒

    这次直接使用delete from emp where cdate<'2018-02-02',看看究竟会发生什么。

    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&lt;#{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>
        
        <delete id="deleteByDate">
            delete from emp where id in (select id from (select id from emp where cdate&lt;#{date,jdbcType=TIMESTAMP}) as tb)
        </delete>
        
        <delete id="deleteEmpByDate">
            delete from emp where cdate&lt;#{date,jdbcType=TIMESTAMP}
        </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);
        
        int deleteByDate(String date);
        
        int deleteEmpByDate(String date);
    }

    代码写好:

    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 BatchDelete3 {
    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 changed=mapper.deleteEmpByDate("2018-02-02");
                session.commit();
                
                System.out.println("All deleted="+changed);
            }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;
        }
    }

    然后塞了一千万条数据一执行,本以为会出现超时异常,回滚段异常,log区异常之类的,结果完全没有,反而还跑出了个最快结果:

    All deleted=8035199
     INFO [main] - Time elapsed:1m9s.

    数据库的情况也证实了删除操作的正确性:

    看来MySql这边千万级数据要删除也就是直接进行的事情,不知道在拿另一环境中的的21张三四百万级的Oracle数据库实验又会是怎样的结果。

    凭感觉,无论是插值还是删除,我虚拟机上的MySql(mysql Ver 14.14 Distrib 5.6.45, for Linux (x86_64) using EditLine wrapper)比单位实装的Oracle要迅速多了。

    --END-- 2019年10月14日14:23:54

  • 相关阅读:
    HDU 4611 Balls Rearrangement 数学
    Educational Codeforces Round 11 D. Number of Parallelograms 暴力
    Knockout.Js官网学习(简介)
    Entity Framework 关系约束配置
    Entity Framework Fluent API
    Entity Framework DataAnnotations
    Entity Framework 系统约定配置
    Entity Framework 自动生成CodeFirst代码
    Entity Framework CodeFirst数据迁移
    Entity Framework CodeFirst尝试
  • 原文地址:https://www.cnblogs.com/heyang78/p/11671293.html
Copyright © 2011-2022 走看看