(一)首先想到的问题是,mysql方面采用何种方式插入
显然不能500万次连接插入
查阅了文章,https://blog.csdn.net/frinder/article/details/38830723
关于批量插入数据之我见(100万级别的数据,mysql)
总结:方法一和方法二很类同,唯一不同的是方法一采用的是“insert into tb (...) values(...),(...)...;”的方式执行插入操作,
方法二则是“insert into tb (...) values (...);insert into tb (...) values (...);...”的方式,要不是测试,我也不知道两者差别是如此之大!
当然,这个只是目前的测试,具体执行时间和步长也有很大关系!如过把步长改为100,可能方法就要几分钟了吧,这个可以自己测试哈。。。
方法三网上很推崇,不过,效率大家也都看到了,1万条记录,耗时6分钟,可见其效率并不理想!而且方法三需要配置spring applicationContext环境才能应用!
显然,第三种方法,以及这个帖子https://blog.csdn.net/silyvin/article/details/79382892使用的spring jdbctamplate batchupdate是对其中的第2种的封装
(二)其次想到的是,如何确保唯一,这里没使用unique索引,而是使用
INSERT ignore INTO test_random (`value`) VALUES
https://www.cnblogs.com/duanxiaojun/p/6855680.html?utm_source=itdadao&utm_medium=referral
避免unique索引在插入数据时的性能损失
18-04-25 22:42:05,985 INFO TestController:387 - TestUnique:4838824
2018-04-25 22:42:06,555 INFO TestController:387 - TestUnique:4848317
2018-04-25 22:42:07,121 INFO TestController:387 - TestUnique:4857823
2018-04-25 22:42:07,684 INFO TestController:387 - TestUnique:4867327
2018-04-25 22:42:08,254 INFO TestController:387 - TestUnique:4876819
2018-04-25 22:42:08,821 INFO TestController:387 - TestUnique:4886321
2018-04-25 22:42:09,377 INFO TestController:387 - TestUnique:4895843
2018-04-25 22:42:10,165 INFO TestController:387 - TestUnique:4905344
2018-04-25 22:42:10,737 INFO TestController:387 - TestUnique:4914880
2018-04-25 22:42:11,318 INFO TestController:387 - TestUnique:4924354
2018-04-25 22:42:11,918 INFO TestController:387 - TestUnique:4933854
2018-04-25 22:42:12,484 INFO TestController:387 - TestUnique:4943352
2018-04-25 22:42:13,087 INFO TestController:387 - TestUnique:4952882
2018-04-25 22:42:13,659 INFO TestController:387 - TestUnique:4962400
2018-04-25 22:42:14,224 INFO TestController:387 - TestUnique:4971891
2018-04-25 22:42:14,789 INFO TestController:387 - TestUnique:4981392
2018-04-25 22:42:15,561 INFO TestController:387 - TestUnique:4990908
2018-04-25 22:42:16,117 INFO TestController:387 - TestUnique:5000386
2018-04-25 22:42:16,129 INFO TestController:407 - cast : 301 s
总耗时301s
public static String generateShortUuid() { StringBuilder str=new StringBuilder();//定义变长字符串 Random random=new Random(); //随机生成数字,并添加到字符串 for(int i=0;i<8;i++){ str.append(random.nextInt(10)); } return str.toString(); } @RequestMapping(value = "testUnique", method = RequestMethod.POST) @ResponseBody @ApiImplicitParams({}) @ApiOperation(value="testUnique") public Object testUnique() { String driver = "com.mysql.jdbc.Driver"; String URL = "jdbc:mysql://bb:3306/test"; Connection conn = null; try { Class.forName(driver); } catch(java.lang.ClassNotFoundException e) { // System.out.println("Connect Successfull."); System.out.println("Cant't load Driver"); } try { conn = DriverManager.getConnection(URL,"bb","nnn"); } catch (SQLException e) { e.printStackTrace(); } Long begin = new Date().getTime(); // sql前缀 String prefix = "INSERT ignore INTO test_random (`value`) VALUES "; int count = 0; while (count <= 5000010) { try { // 保存sql后缀j 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 <= 100; j++) { String id = generateShortUuid(); // 构建sql后缀 suffix.append("('"); suffix.append(id); suffix.append("'),"); } // 构建完整sql String sql = prefix + suffix.substring(0, suffix.length() - 1); // 添加执行sql pst.addBatch(sql); // 执行操作 pst.executeBatch(); // 提交事务 conn.commit(); // 清空上一次添加的数据 suffix = new StringBuffer(); } // 头等连接 pst.close(); String sqlcount = "select count(1) from test_random"; count = jdbcTemplate.queryForObject(sqlcount, Integer.class); logger.info("TestUnique:"+count); } catch (SQLException e) { e.printStackTrace(); logger.error(e); break; } } try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } // 结束时间 Long end = new Date().getTime(); // 耗时 logger.info("cast : " + (end - begin) / 1000 + " s"); return (end - begin) / 1000; }