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

测试数据库为MySQL!!!

方法一:

  1. public static void insert() {
  2. // 开时时间
  3. Long begin = new Date().getTime();
  4. // sql前缀
  5. String prefix = "INSERT INTO tb_big_data (count, create_time, random) VALUES ";
  6. try {
  7. // 保存sql后缀
  8. StringBuffer suffix = new StringBuffer();
  9. // 设置事务为非自动提交
  10. conn.setAutoCommit(false);
  11. // Statement st = conn.createStatement();
  12. // 比起st,pst会更好些
  13. PreparedStatement pst = conn.prepareStatement("");
  14. // 外层循环,总提交事务次数
  15. for (int i = 1; i <= 100; i++) {
  16. // 第次提交步长
  17. for (int j = 1; j <= 10000; j++) {
  18. // 构建sql后缀
  19. suffix.append("(" + j * i + ", SYSDATE(), " + i * j
  20. * Math.random() + "),");
  21. }
  22. // 构建完整sql
  23. String sql = prefix + suffix.substring(0, suffix.length() - 1);
  24. // 添加执行sql
  25. pst.addBatch(sql);
  26. // 执行操作
  27. pst.executeBatch();
  28. // 提交事务
  29. conn.commit();
  30. // 清空上一次添加的数据
  31. suffix = new StringBuffer();
  32. }
  33. // 头等连接
  34. pst.close();
  35. conn.close();
  36. } catch (SQLException e) {
  37. e.printStackTrace();
  38. }
  39. // 结束时间
  40. Long end = new Date().getTime();
  41. // 耗时
  42. System.out.println("cast : " + (end - begin) / 1000 + " ms");
  43. }
  1. public static void insert() {
  2. // 开时时间
  3. Long begin = new Date().getTime();
  4. // sql前缀
  5. String prefix = "INSERT INTO tb_big_data (count, create_time, random) VALUES ";
  6. try {
  7. // 保存sql后缀
  8. StringBuffer suffix = new StringBuffer();
  9. // 设置事务为非自动提交
  10. conn.setAutoCommit(false);
  11. // Statement st = conn.createStatement();
  12. // 比起st,pst会更好些
  13. PreparedStatement pst = conn.prepareStatement("");
  14. // 外层循环,总提交事务次数
  15. for (int i = 1; i <= 100; i++) {
  16. // 第次提交步长
  17. for (int j = 1; j <= 10000; j++) {
  18. // 构建sql后缀
  19. suffix.append("(" + j * i + ", SYSDATE(), " + i * j
  20. * Math.random() + "),");
  21. }
  22. // 构建完整sql
  23. String sql = prefix + suffix.substring(0, suffix.length() - 1);
  24. // 添加执行sql
  25. pst.addBatch(sql);
  26. // 执行操作
  27. pst.executeBatch();
  28. // 提交事务
  29. conn.commit();
  30. // 清空上一次添加的数据
  31. suffix = new StringBuffer();
  32. }
  33. // 头等连接
  34. pst.close();
  35. conn.close();
  36. } catch (SQLException e) {
  37. e.printStackTrace();
  38. }
  39. // 结束时间
  40. Long end = new Date().getTime();
  41. // 耗时
  42. System.out.println("cast : " + (end - begin) / 1000 + " ms");
  43. }

输出时间:cast : 23 ms

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

方法二:

  1. public static void insertRelease() {
  2. Long begin = new Date().getTime();
  3. String sql = "INSERT INTO tb_big_data (count, create_time, random) VALUES (?, SYSDATE(), ?)";
  4. try {
  5. conn.setAutoCommit(false);
  6. PreparedStatement pst = conn.prepareStatement(sql);
  7. for (int i = 1; i <= 100; i++) {
  8. for (int k = 1; k <= 10000; k++) {
  9. pst.setLong(1, k * i);
  10. pst.setLong(2, k * i);
  11. pst.addBatch();
  12. }
  13. pst.executeBatch();
  14. conn.commit();
  15. }
  16. pst.close();
  17. conn.close();
  18. } catch (SQLException e) {
  19. e.printStackTrace();
  20. }
  21. Long end = new Date().getTime();
  22. System.out.println("cast : " + (end - begin) / 1000 + " ms");
  23. }
  1. public static void insertRelease() {
  2. Long begin = new Date().getTime();
  3. String sql = "INSERT INTO tb_big_data (count, create_time, random) VALUES (?, SYSDATE(), ?)";
  4. try {
  5. conn.setAutoCommit(false);
  6. PreparedStatement pst = conn.prepareStatement(sql);
  7. for (int i = 1; i <= 100; i++) {
  8. for (int k = 1; k <= 10000; k++) {
  9. pst.setLong(1, k * i);
  10. pst.setLong(2, k * i);
  11. pst.addBatch();
  12. }
  13. pst.executeBatch();
  14. conn.commit();
  15. }
  16. pst.close();
  17. conn.close();
  18. } catch (SQLException e) {
  19. e.printStackTrace();
  20. }
  21. Long end = new Date().getTime();
  22. System.out.println("cast : " + (end - begin) / 1000 + " ms");
  23. }

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

控制台输出:cast : 111 ms

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

方法三:

  1. public static void insertBigData(SpringBatchHandler sbh) {
  2. Long begin = new Date().getTime();
  3. JdbcTemplate jdbcTemplate = sbh.getJdbcTemplate();
  4. final int count = 10000;
  5. String sql = "INSERT INTO tb_big_data (count, create_time, random) VALUES (?, SYSDATE(), ?)";
  6. jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
  7. // 为prepared statement设置参数。这个方法将在整个过程中被调用的次数
  8. public void setValues(PreparedStatement pst, int i)
  9. throws SQLException {
  10. pst.setLong(1, i);
  11. pst.setInt(2, i);
  12. }
  13. // 返回更新的结果集条数
  14. public int getBatchSize() {
  15. return count;
  16. }
  17. });
  18. Long end = new Date().getTime();
  19. System.out.println("cast : " + (end - begin) / 1000 + " ms");
  20. }
  1. public static void insertBigData(SpringBatchHandler sbh) {
  2. Long begin = new Date().getTime();
  3. JdbcTemplate jdbcTemplate = sbh.getJdbcTemplate();
  4. final int count = 10000;
  5. String sql = "INSERT INTO tb_big_data (count, create_time, random) VALUES (?, SYSDATE(), ?)";
  6. jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
  7. // 为prepared statement设置参数。这个方法将在整个过程中被调用的次数
  8. public void setValues(PreparedStatement pst, int i)
  9. throws SQLException {
  10. pst.setLong(1, i);
  11. pst.setInt(2, i);
  12. }
  13. 		// 返回更新的结果集条数
  14. 		public int getBatchSize() {
  15. 			return count;
  16. 		}
  17. 	});
  18. 	Long end = new Date().getTime();
  19. 	System.out.println("cast : " + (end - begin) / 1000 + " ms");
  20. }</pre><br>
  21.  
  22. 该方法采用的是spring batchUpdate执行,因效率问题,数据量只有1万条!

  23. 执行时间:cast : 387 ms

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

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

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

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

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

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

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

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

关于批量插入数据之我见(100万级别的数据,mysql) (转)的更多相关文章

  1. Mysql数据库实践操作之————批量插入数据(100万级别的数据)

    第一种方法:使用insert into 插入 从Redis每次获取100条数据,根据条件去插入到Mysql数据库中: 条件: 如果当前队列中的值大于1000条,则会自动的条用该方法,该方法每次获取从队 ...

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

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

  3. 如何通过Dataphin构建数据中台新增100万用户?

    欢迎来到数据中台小讲堂!这一期我们来看看,作为阿里巴巴数据中台(OneData - OneModel.OneID.OneService)方法论的产品载体,Dataphin如何帮助传统零售企业实现数字化 ...

  4. 极限挑战—C#+ODP 100万条数据导入Oracle数据库仅用不到1秒

    链接地址:http://www.cnblogs.com/armyfai/p/4646213.html 要:在这里我们将看到的是C#中利用ODP实现在Oracle数据库中瞬间导入百万级数据,这对快速批量 ...

  5. 多线程查询数据,将结果存入到redis中,最后批量从redis中取数据批量插入数据库中【我】

    多线程查询数据,将结果存入到redis中,最后批量从redis中取数据批量插入数据库中 package com.xxx.xx.reve.service; import java.util.ArrayL ...

  6. .Net中DataAdapter批量插入和更新数据总结

    前言 前段时间一直在忙着项目上线,在做项目的同时遇到了一些之前不曾碰到的问题,因为没有经验,只能从网上找一些相关的解决方案,但是网上提供的资料实在是太杂,有的根本不能用,耗时又耗力. 我希望把我这段时 ...

  7. Hibernate 数据的批量插入、更新和删除

    4.2  Hibernate的批量处理 Hibernate完全以面向对象的方式来操作数据库,当程序里以面向对象的方式操作持久化对象时,将被自动转换为对数据库的操作.例如调用Session的delete ...

  8. 利用pipeline批量插入数据到redis

    在推荐系统中,推荐候选集格式一般是,itemid itemid_list.要把itemid作为key,推荐列表作为value批量插入到redis. 比如文件cf.data为: cf_763500210 ...

  9. MySQL on duplicate key update 批量插入并更新已存在数据

    业务上经常存在一种现象,需要批量往表中插入多条数据,但在执行过程中,很可能因为唯一键冲突,而导致批量插入失败.因此需要事先判断哪些数据是重复的,哪些是新增的.比较常用的处理方法就是找出已存在的数据,并 ...

随机推荐

  1. js实现日期格式化

    <!DOCTYPE html><html><head> <meta charset="utf-8"> <meta http-e ...

  2. Aspose.words 书签定位

    1. 简介 Aspose.words 可以在不使用 Microsoft.Word 的情况下生成.修改.转换.打印文档.不依赖office组件,这一点给我们提供了极大的便利性,可以简单的引入 DLL(D ...

  3. 如何生成Azure SAS Token

    在Azure PaaS服务密钥的安全性文章中,提到过客户端实际上发送的是Token,而不是密钥.那么Token是该如何生成呢? Azure相应服务的SDK其实都提供了或者内置了生成Token的方法,可 ...

  4. Maven基础

    Maven基础 maven核心内容:依赖管理. Maven是Apache组织的开源项目,是项目构建工具.用来管理jar包之间的相互依赖关系 Maven是一个项目构建和管理的工具,提供了帮助管理,构建, ...

  5. .net ElasticSearch-Sql 扩展类

    官方提供的是java sdk,并支持jdbc方式的查询结果输出;但是却没有.net sdk的支持. 开发 ElasticSearch-Sql 第三方开源项目的.net sdk,未来集成入bsf框架.( ...

  6. Maven安装及使用-超级图文初级篇-

    针对新手刚接触maven,并且不知道如何去搭建和使用maven,那么我来写一篇浅显易懂的初级篇教程吧. 不同的是,别人会先将概念再安装,我来帮大家先搭建好以后再去看概念,不然概念会变的很模糊. 安装: ...

  7. 快速搞定selenium grid分布式

    写这篇文章,似乎有点重复造轮子的嫌疑.当看了几篇相关文章后,我还是决定把半年前的半成品给完成了. 以传统的方式部署分布式Selenium Grid集群需要耗费大量时间和机器成本来准备测试环境. Sna ...

  8. Java单线程文件下载,支持断点续传功能

    前言: 程序下载文件时,有时会因为各种各样的原因下载中断,对于小文件来说影响不大,可以快速重新下载,但是下载大文件时,就会耗费很长时间,所以断点续传功能对于大文件很有必要. 文件下载的断点续传: 1. ...

  9. Angularjs跳转切换至对应选项卡

    //跳转前页面 <div class="list user_order" ng-click="userOpen('userOrder',0)"> & ...

  10. [BZOJ 2500] 幸福的道路

    照例先贴题面(汪汪汪) 2500: 幸福的道路 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 368  Solved: 145[Submit][Sta ...