因前段时间去面试,问到如何高效向数据库插入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中可用性还是很高的!
?
刚才开始研究大数据方面的问题,以上也只是真实测试的结果,并不一定就是事实,有好的建议,大家请指正,谢谢!
相互学习,才能进步更快!
?
晚点会把源码发上来,大家可以直接去下载测试!
版权声明:本文为博主原创文章,未经博主允许不得转载。