對大數據的批量導入MySQL數據庫


自己的庫里有索引在用insert導入數據時會變慢很多

  使用事務+批量導入

    可以配置使用spring+mybatis整合的方式關閉自動提交事務(地址),選擇批量導入每一百條導入使用list存儲值傳入到mybatis中

      http://x125858805.iteye.com/blog/2369243

          list.add(bill); //自己選擇插入對象
                if(list.size()==1000) {
                    Result<Integer> num = billCheckService.batchInsert(list); //將會調用下面的配置文件
                    countnum+=num.getData();
                    for(int i = 0; i < num.getData();i++) {
                        countmoney+=list.get(i).getPayAmount();
                    }
                    list.clear(); 
                }
<insert id="batchInsert" parameterType="java.util.List" >
        insert into t_pay_bill_file_detail (file_id,pay_order_no,third_trade_no)
        values
        <foreach collection="list" item="item" index="index" separator=",">
            (
            #{item.fileId},
            #{item.payOrderNo},
            #{item.thirdTradeNo}
            )
        </foreach>
    </insert>

或者使用原始的jdbc關閉事務進行批量提交

conn.setAutoCommit(false); //一句話就可以啦

          ps.addBatch();
                if(list.size()==1000) {int[] num = ps.executeBatch();
                    conn.commit();
          }

前兩個自己試驗的時候大概花的時間都一樣,自己又試驗了一個按文件處理的語句進行jdbc插入,是最快的方式了,可以在SQL后面制定插入固定字段的值,前提是文件的順序必須是一樣的,注意事項:

character set utf8 --------這里是utf8不是utf-8;
fields terminated by ','----文件中每個字段是按‘,’分割的,如.csv文件
lines terminated by '\\n'---每行代表一個記錄;
        Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://192.168.2.18:3306/fi?characterEncoding=utf8&allowMultiQueries=true&autoReconnect=true&failOverReadOnly=false",
                    username,password);
            reader = new BufferedReader(new InputStreamReader(file.getInputStream())); //因為自己是從前端傳進來一個file(MultipartFile類型)
            file1=File.createTempFile("gjy",".txt",new File("E:"));  //E:后面不用寫//來代表在盤符下,SQL會默認缺省的,不然添加后報錯
       String sql = "load data local infile "+'"'+ file1.getAbsolutePath()+'"' 
                    +" into table t_pay_bill_file_detailcopy character set utf8 fields terminated by ',' "
                    + "lines terminated by '\\n' "
                    + "(`file_id`,`trans_type`,`pay_channel_id`,`pay_order_no`,`third_trade_no`,`trans_date`,`pay_amount`) ";
            ps = conn.prepareStatement(sql);
            ps.execute();
       file1.deleteOnExit(); //程序退出時刪除臨時文件

這個方式雖然快是快,但是對文件的要求太高,客戶不可能對程序理解,只知道傳進來文件,所以自己取到file對象都會對file進行按行讀取並進行判斷重寫寫入臨時文件

這就又有個問題,讀取寫入需要花費太多時間,因為自己需要各種業務邏輯進行處理。目前正在努力解決中,如果大家有什么好的方法可以提出來一下!

 

 ps:關注一下本人公眾號,每周都有新更新哦!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM