zoukankan      html  css  js  c++  java
  • 关于批量插入数据之我见(100万级别的数据,mysql)

    因前段时间去面试,问到怎样高效向数据库插入10万条记录,之前没处理过类似问题。也没看过相关资料,结果没答上来,今天就查了些资料。总结出三种方法:

    測试数据库为mysql!!!

    方法一:

    public static void insert() {
    		// 开时时间
    		Long begin = 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 (int i = 1; i <= 100; i++) {
    				// 第次提交步长
    				for (int j = 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();
    		}
    		// 结束时间
    		Long end = new Date().getTime();
    		// 耗时
    		System.out.println("cast : " + (end - begin) / 1000 + " ms");
    	}


    输出时间:cast : 23 ms

    该方法眼下測试是效率最高的方法!




    方法二:

    public static void insertRelease() {
    		Long begin = 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 (int i = 1; i <= 100; i++) {
    				for (int k = 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();
    		}
    		Long end = new Date().getTime();
    		System.out.println("cast : " + (end - begin) / 1000 + " ms");
    	}

    注:凝视就没有了,和上面类同,以下会有分析!

    控制台输出:cast : 111 ms

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



    方法三:

    public static void insertBigData(SpringBatchHandler sbh) {
    		Long begin = new Date().getTime();
    		JdbcTemplate jdbcTemplate = sbh.getJdbcTemplate();
    		final int count = 10000;
    		String sql = "INSERT INTO tb_big_data (count, create_time, random) VALUES (?, SYSDATE(), ?

    )"; jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() { // 为prepared statement设置參数。这种方法将在整个过程中被调用的次数 public void setValues(PreparedStatement pst, int i) throws SQLException { pst.setLong(1, i); pst.setInt(2, i); } // 返回更新的结果集条数 public int getBatchSize() { return count; } }); Long end = 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中可用性还是非常高的!


    刚才開始研究大数据方面的问题。以上也仅仅是真实測试的结果,并不一定就是事实,有好的建议。大家请指正。谢谢!

    相互学习,才干进步更快。


    晚点会把源代码发上来。大家能够直接去下载測试!

  • 相关阅读:
    codeforces 459 C. Pashmak and Buses(思维)
    poj 2763 Housewife Wind(树链剖分+单点查询+区间修改)
    codeforces E. Phone Talks(dp)
    BZOJ 1036: [ZJOI2008]树的统计Count(树链剖分+单点更新+区间求和+区间求最大值)
    SPOJ
    hdu 3966 Aragorn's Story(树链剖分+区间修改+单点查询)
    codeforces H. Queries for Number of Palindromes(区间dp)
    codeforces 245 D. Restoring Table(位运算+思维)
    codeforces 402 D. Upgrading Array(数论+贪心)
    codeforces 793 D. Presents in Bankopolis(记忆化搜索)
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/6756622.html
Copyright © 2011-2022 走看看