【Oracle/Java】以Insert ALL方式向表中插入百萬條記錄,耗時9分17秒


由於按一千條一插程序長期無反應,之后改為百條一插方式,運行完發現插入百萬記錄需要9m17s,雖然比MySQL效率差,但比單條插入已經好不少了。

對Oracle的批量插入語法不明的請參考:https://www.cnblogs.com/xiandedanteng/p/11806720.html

代碼如下:

package com.hy;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.MessageFormat;

/**
 * 百萬數據插入Oracle表中
 * @author horn1
 *
 */
public class MillionInserter {
    
    // 連接到數據庫的四大屬性
    private static final String DRIVER = "oracle.jdbc.driver.OracleDriver";
    private static final String DBURL = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";
    private static final String USER = "system";
    private static final String PSWD = "XXXX";
    
    public void batchInsert(int count) {
        Connection conn = null;
        Statement stmt = null;
        
        try{
            long startTime = System.currentTimeMillis();
            
            Class.forName(DRIVER).newInstance();
            conn = DriverManager.getConnection(DBURL, USER, PSWD);
            stmt = conn.createStatement();
            
            int BatchSize=100;
            int index=0;
            int times=count/BatchSize;
            for(int i=0;i<times;i++) {
                StringBuilder sb=new StringBuilder();
                sb.append("INSERT ALL ");
                
                for(int j=0;j<BatchSize;j++) {
                    index=i*BatchSize+j;
                    String name="M"+index;
                    int age=j % 100;
                    
                    String raw=" INTO firsttb(NAME, age,createdtime) values(''{0}'',''{1}'',sysdate) ";
                    Object[] arr={name,age};
                    String particialSql=MessageFormat.format(raw, arr);
                    sb.append(particialSql);
                }
                
                sb.append("select * from dual");
                String sql = sb.toString();
                stmt.executeUpdate(sql);
                System.out.println("#"+i+" "+BatchSize+" records inserted");
            }
            
            long endTime = System.currentTimeMillis();
            System.out.println("Time elapsed:" + sec2DHMS((endTime - startTime)/1000) );
            
            String sql = "select count(*) as cnt from firsttb";
            ResultSet rs = stmt.executeQuery(sql);

            while (rs.next()) {
                String cnt = rs.getString("cnt");
                System.out.println("當前記錄數:"+cnt);
            }            
            
        } catch (Exception e) {
            System.out.print(e.getMessage());
        } finally {
            try {
                stmt.close();
                conn.close();
            } catch (SQLException e) {
                System.out.print("Can't close stmt/conn because of " + e.getMessage());
            }
        }
    }
    
    /**
         * 將秒轉化為日時分秒
     * @param secondCount
     * @return
     */
    private static String sec2DHMS(long secondCount) {
        String retval = null;

        long days = secondCount / (60 * 60 * 24);
        long hours = (secondCount % (60 * 60 * 24)) / (60 * 60);
        long minutes = (secondCount % (60 * 60)) / 60;
        long seconds = secondCount % 60;
        
        String strSeconds="";
        if(seconds!=0) {
            strSeconds=seconds + "s";
        }

        if (days > 0) {
            retval = days + "d" + hours + "h" + minutes + "m" + strSeconds;
        } else if (hours > 0) {
            retval = hours + "h" + minutes + "m" + strSeconds;
        } else if (minutes > 0) {
            retval = minutes + "m" + strSeconds;
        } else {
            retval = strSeconds;
        }

        return retval;
    }
    
    /**
     * 執行點
     * @param args
     */
    public static void main(String[] args) {
        MillionInserter mi=new MillionInserter();
        mi.batchInsert(1000000);
    }
}

輸出:

#9987 100 records inserted
#9988 100 records inserted
#9989 100 records inserted
#9990 100 records inserted
#9991 100 records inserted
#9992 100 records inserted
#9993 100 records inserted
#9994 100 records inserted
#9995 100 records inserted
#9996 100 records inserted
#9997 100 records inserted
#9998 100 records inserted
#9999 100 records inserted
Time elapsed:9m17s
當前記錄數:1000000

到此真正掌握了Oracle的Insert ALL語法,並確認了其真實效率,今天又取得了一個小小的突破,重走長征路又邁出了小小卻堅實的一步。

表的表結構請見:https://www.cnblogs.com/xiandedanteng/p/11691113.html

--END-- 2019年11月9日11:19:01


免責聲明!

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



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