• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

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

mysql 搞代码 4年前 (2022-01-09) 34次浏览 已收录 0个评论

因前段时间去面试,问到如何高效向数据库插入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();			// 设置事务为非自动提交<div style="color:transparent">本文来源gaodai.ma#com搞##代!^码网(</div>			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中可用性还是很高的!

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

相互学习,才能进步更快!

晚点会把源码发上来,大家可以直接去下载测试!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:关于批量插入数据之我见(100万级别的数据,mysql)_MySQL

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址