插入500萬條8位隨機唯一數字串
(一)首先想到的問題是,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,985INFO TestController:387 - TestUnique:4838824
2018-04-25 22:42:06,555INFO TestController:387 - TestUnique:4848317
2018-04-25 22:42:07,121INFO TestController:387 - TestUnique:4857823
2018-04-25 22:42:07,684INFO TestController:387 - TestUnique:4867327
2018-04-25 22:42:08,254INFO TestController:387 - TestUnique:4876819
2018-04-25 22:42:08,821INFO TestController:387 - TestUnique:4886321
2018-04-25 22:42:09,377INFO TestController:387 - TestUnique:4895843
2018-04-25 22:42:10,165INFO TestController:387 - TestUnique:4905344
2018-04-25 22:42:10,737INFO TestController:387 - TestUnique:4914880
2018-04-25 22:42:11,318INFO TestController:387 - TestUnique:4924354
2018-04-25 22:42:11,918INFO TestController:387 - TestUnique:4933854
2018-04-25 22:42:12,484INFO TestController:387 - TestUnique:4943352
2018-04-25 22:42:13,087INFO TestController:387 - TestUnique:4952882
2018-04-25 22:42:13,659INFO TestController:387 - TestUnique:4962400
2018-04-25 22:42:14,224INFO TestController:387 - TestUnique:4971891
2018-04-25 22:42:14,789INFO TestController:387 - TestUnique:4981392
2018-04-25 22:42:15,561INFO TestController:387 - TestUnique:4990908
2018-04-25 22:42:16,117INFO TestController:387 - TestUnique:5000386
2018-04-25 22:42:16,129INFO 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;
}