关于批量插入数据(100万级别的数据,mysql)

来源:互联网 发布:小明永久域名首页台湾 编辑:程序博客网 时间:2024/06/13 05:21

测试数据库为mysql!!!

方法一:

public static void insert() {
        // 开时时间
        Longbegin= new Date().getTime();
        // sql前缀
        String prefix = "INSERT INTO tb_big_data (count, create_time, random) VALUES ";
        try {
            // 保存sql后缀
            StringBuffer suffix = new StringBuffer();
            // 设置事务为非自动提交
            conn.setAutoCommit(false);
            // Statement st = conn.createStatement();
            // 比起st,pst会更好些
            PreparedStatement pst = conn.prepareStatement("");
            // 外层循环,总提交事务次数
            for(inti = 1; i <= 100; i++) {
                // 第次提交步长
                for(intj = 1; j <= 10000; j++) {
                    // 构建sql后缀
                    suffix.append("("+ j * i + ", SYSDATE(), " + i * j
                            * Math.random() + "),");
                }
                // 构建完整sql
                String sql = prefix + suffix.substring(0, suffix.length() - 1);
                // 添加执行sql
                pst.addBatch(sql);
                // 执行操作
                pst.executeBatch();
                // 提交事务
                conn.commit();
                // 清空上一次添加的数据
                suffix = new StringBuffer();
            }
            // 头等连接
            pst.close();
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        // 结束时间
        Longend= new Date().getTime();
        // 耗时
        System.out.println("cast : " + (end- begin) / 1000 + " ms");
方法二:    }

输出时间:cast : 23 ms

该方法目前测试是效率最高的方法!


方法二:

publicstatic void insertRelease() {
        Longbegin= new Date().getTime();
        String sql = "INSERT INTO tb_big_data (count, create_time, random) VALUES (?, SYSDATE(), ?)";
        try {
            conn.setAutoCommit(false);
            PreparedStatement pst = conn.prepareStatement(sql);
            for(inti = 1; i <= 100; i++) {
                for(intk = 1; k <= 10000; k++) {
                    pst.setLong(1, k * i);
                    pst.setLong(2, k * i);
                    pst.addBatch();
                }
                pst.executeBatch();
                conn.commit();
            }
            pst.close();
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        Longend= new Date().getTime();
        System.out.println("cast : " + (end- begin) / 1000 + " ms");
    }

控制台输出:cast : 111 ms

执行时间是上面方法的5倍!


方法三:

publicstatic void insertBigData(SpringBatchHandler sbh) {
        Longbegin= new Date().getTime();
        JdbcTemplate jdbcTemplate = sbh.getJdbcTemplate();
        finalintcount = 10000;
        String sql = "INSERT INTO tb_big_data (count, create_time, random) VALUES (?, SYSDATE(), ?)";
        jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
            // 为prepared statement设置参数。这个方法将在整个过程中被调用的次数
            publicvoid setValues(PreparedStatement pst, inti)
                    throws SQLException {
                pst.setLong(1, i);
                pst.setInt(2, i);
            }
 
            // 返回更新的结果集条数
            publicint getBatchSize() {
                returncount;
            }
        });
        Longend= new Date().getTime();
        System.out.println("cast : " + (end- begin) / 1000 + " ms");
    }

该方法采用的是spring batchUpdate执行,因效率问题,数据量只有1万条!

执行时间:cast : 387 ms


总结:方法一和方法二很类同,唯一不同的是方法一采用的是“insert into tb (...) values(...),(...)...;”的方式执行插入操作,

方法二则是“insert into tb (...) values (...);insert into tb (...) values (...);...”的方式,要不是测试,我也不知道两者差别是如此之大!

当然,这个只是目前的测试,具体执行时间和步长也有很大关系!如过把步长改为100,可能方法就要几分钟了吧,这个可以自己测试哈。。。

方法三网上很推崇,不过,效率大家也都看到了,1万条记录,耗时6分钟,可见其效率并不理想!而且方法三需要配置spring applicationContext环境才能应用!

不过,方法三在ssh/spring-mvc中可用性还是很高的!


0 0
原创粉丝点击