生活随笔
收集整理的這篇文章主要介紹了
关于批量插入数据之我见(100万级别的数据,mysql)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
2019獨角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
因前段時間去面試,問到如何高效向數(shù)據(jù)庫插入10萬條記錄,之前沒處理過類似問題,也沒看過相關(guān)資料,結(jié)果沒答上來,今天就查了些資料,總結(jié)出三種方法:
測試數(shù)據(jù)庫為mysql!!!
方法一:
?
[java]?view plain?copy
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();??????????????//?設(shè)置事務(wù)為非自動提交??????????????conn.setAutoCommit(false);??????????????//?Statement?st?=?conn.createStatement();??????????????//?比起st,pst會更好些??????????????PreparedStatement?pst?=?conn.prepareStatement("");??????????????//?外層循環(huán),總提交事務(wù)次數(shù)??????????????for?(int?i?=?1;?i?<=?100;?i++)?{??????????????????//?第次提交步長??????????????????for?(int?j?=?1;?j?<=?10000;?j++)?{??????????????????????//?構(gòu)建sql后綴??????????????????????suffix.append("("?+?j?*?i?+?",?SYSDATE(),?"?+?i?*?j??????????????????????????????*?Math.random()?+?"),");??????????????????}??????????????????//?構(gòu)建完整sql??????????????????String?sql?=?prefix?+?suffix.substring(0,?suffix.length()?-?1);??????????????????//?添加執(zhí)行sql??????????????????pst.addBatch(sql);??????????????????//?執(zhí)行操作??????????????????pst.executeBatch();??????????????????//?提交事務(wù)??????????????????conn.commit();??????????????????//?清空上一次添加的數(shù)據(jù)??????????????????suffix?=?new?StringBuffer();??????????????}??????????????//?頭等連接??????????????pst.close();??????????????conn.close();??????????}?catch?(SQLException?e)?{??????????????e.printStackTrace();??????????}??????????//?結(jié)束時間??????????Long?end?=?new?Date().getTime();??????????//?耗時??????????System.out.println("cast?:?"?+?(end?-?begin)?/?1000?+?"?ms");??????}???
?
輸出時間:cast : 23 ms
該方法目前測試是效率最高的方法!
?
?
?
方法二:
?
[java]?view plain?copy
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
執(zhí)行時間是上面方法的5倍!
?
?
方法三:
?
[java]?view plain?copy
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設(shè)置參數(shù)。這個方法將在整個過程中被調(diào)用的次數(shù)??????????????public?void?setValues(PreparedStatement?pst,?int?i)??????????????????????throws?SQLException?{??????????????????pst.setLong(1,?i);??????????????????pst.setInt(2,?i);??????????????}????????????????//?返回更新的結(jié)果集條數(shù)??????????????public?int?getBatchSize()?{??????????????????return?count;??????????????}??????????});??????????Long?end?=?new?Date().getTime();??????????System.out.println("cast?:?"?+?(end?-?begin)?/?1000?+?"?ms");??????}??
該方法采用的是spring batchUpdate執(zhí)行,因效率問題,數(shù)據(jù)量只有1萬條!
?
執(zhí)行時間:cast : 387 ms
?
?
?
?
總結(jié):方法一和方法二很類同,唯一不同的是方法一采用的是“insert into tb (...) values(...),(...)...;”的方式執(zhí)行插入操作,
方法二則是“insert into tb (...) values (...);insert into tb (...) values (...);...”的方式,要不是測試,我也不知道兩者差別是如此之大!
當(dāng)然,這個只是目前的測試,具體執(zhí)行時間和步長也有很大關(guān)系!如過把步長改為100,可能方法就要幾分鐘了吧,這個可以自己測試哈。。。
方法三網(wǎng)上很推崇,不過,效率大家也都看到了,1萬條記錄,耗時6分鐘,可見其效率并不理想!而且方法三需要配置spring applicationContext環(huán)境才能應(yīng)用!
不過,方法三在ssh/spring-mvc中可用性還是很高的!
?
剛才開始研究大數(shù)據(jù)方面的問題,以上也只是真實測試的結(jié)果,并不一定就是事實,有好的建議,大家請指正,謝謝!
相互學(xué)習(xí),才能進步更快!
?
晚點會把源碼發(fā)上來,大家可以直接去下載測試!
轉(zhuǎn)載于:https://my.oschina.net/u/1018004/blog/1571241
總結(jié)
以上是生活随笔為你收集整理的关于批量插入数据之我见(100万级别的数据,mysql)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。