Oracle高效批量插入數據(150萬行4.7分鍾)


一、准備工作

 建表

CREATE TABLE TEMP_20200210
(
	DMC VARCHAR2(100);
)

用程序拼接如下的批量插入的SQL

INSERT INTO TEMP_20200210 (DMC)
	SELECT CD.* FROM 
	(
		SELECT 1234567 FROM DUAL UNION
		SELECT 1234568 FROM DUAL UNION
		SELECT 1234568 FROM DUAL 
	) CD

在C盤文件夾下放一個1.txt文件目錄為C:\1.TXT 里面的內容如下。里面有大約150萬行數據,36M左右

二、實踐

 直接上代碼,需要引入oracle的包。

package connect;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

public class oracle {
		//數據庫連接對象
	    private static Connection conn = null;
	     
	    private static String driver = "oracle.jdbc.driver.OracleDriver"; //驅動
	     
	    private static String url = "jdbc:oracle:thin:@//ip:1521/orcl"; //連接字符串 ip替換成實際ip地址
	     
	    private static String username = "globalb"; //用戶名
	     
	    private static String password = "globalb"; //密碼
	     
	     
	    // 獲得連接對象
	    private static synchronized Connection getConn(){
	        if(conn == null){
	            try {
	                Class.forName(driver);
	                conn = DriverManager.getConnection(url, username, password);
	            } catch (ClassNotFoundException e) {
	                e.printStackTrace();
	            }catch (SQLException e) {
	                e.printStackTrace();
	            }
	        }
	        return conn;
	    }
	     
	    //執行查詢語句
	    public void query(String sql, boolean isSelect) throws SQLException{
	        PreparedStatement pstmt;
	         
	        try {
	            pstmt = getConn().prepareStatement(sql);
	            //建立一個結果集,用來保存查詢出來的結果
	            ResultSet rs = pstmt.executeQuery();
	            while (rs.next()) {
	                String name = rs.getString("DMC");
	                System.out.println(name);
	            }
	            rs.close();
	            pstmt.close();
	        } catch (SQLException e) {
	            e.printStackTrace();
	        }
	    }
	     
	    public void query(String sql) throws SQLException{
	        PreparedStatement pstmt;
	        pstmt = getConn().prepareStatement(sql);
	        pstmt.execute();
	        pstmt.close();
	    }
	     
	     
	    //關閉連接
	    public void close(){
	        try {
	            getConn().close();
	             
	        } catch (SQLException e) {
	            e.printStackTrace();
	        }
	    }
	  //執行查詢語句
	    public static void  insert(List list) throws SQLException{
	        Statement pstmt;
	        String sql ="INSERT INTO IPAM.TEMP_20200210 (DMC) SELECT CD.* FROM ("; //SELECT 1234567 FROM DUAL UNION 
	        for(int i= 0;i<list.size();i++){
	        	sql = sql+"SELECT "+list.get(i)+" FROM DUAL UNION ";
	        }
	        sql = sql.substring(0, sql.length()-6);
	        sql=sql+")CD";
	        //System.out.println(sql);
	        try {
	            pstmt = getConn().createStatement();
	            //建立一個結果集,用來保存查詢出來的結果
	            pstmt.executeQuery(sql);
	            pstmt.close();
	        } catch (SQLException e) {
	            e.printStackTrace();
	        }
	    }
	    public static void main(String[] args) throws SQLException, IOException{
	    	Long a  = System.currentTimeMillis();
	    	 FileReader  fileReader =new FileReader("C:\\1.txt");
	         BufferedReader bufferedReader =new BufferedReader(fileReader);
	         StringBuilder  stringBuilder =new StringBuilder();
	           List<String>  strings =new ArrayList<>();
	            String  str=null;
	            while ((str=bufferedReader.readLine())!=null) {
	                //System.out.println(str);
	                  if (str.trim().length()>2) {
	                     strings.add(str);
	                 }  
	         }
	            System.out.println("total:"+strings.size());
	    	List l = strings;
	    	if(l.size()>0){
	    		if(l.size()<=2000){//每次只插入2000條數據,ORACLE插入字符串不能大於32k
	    			insert(l);
	    	    }else{
	    	            int times = (int)Math.ceil(l.size()/2000.0 );//這里的數字必須是浮點數,否則無法向上取整
	    	            for(int i=0; i<times; i++ ){
	    	          	insert(l.subList(i*2000, Math.min((i+1)*2000, l.size())));
	    	          	System.out.println("執行第"+(i+1)+"次");
	    	            }
	    	    }
	    	}
	    	Long b = System.currentTimeMillis();
	    	System.out.println("耗時:"+(b-a)+"ms");
	    }
	}

  

三、運行結果

282秒大約4.7分鍾左右。

四、總結

以上工作的數據庫環境為oracle11g rac ,java版本為java8。

操作系統為windows 2012R2 。

中心思想為分段批量插入,核心代碼是參考其他博文的,原文是使用mybatis批量向oracle中插入數據。

if(l.size()>0){
	if(l.size()<=2000){//每次只插入2000條數據,ORACLE插入字符串不能大於32k
		insert(l);
          }else{
            int times = (int)Math.ceil(l.size()/2000.0 );//這里的數字必須是浮點數,否則無法向上取整
            for(int i=0; i<times; i++ ){
          	insert(l.subList(i*2000, Math.min((i+1)*2000, l.size())));
            }
          }
}

  

當然也可以擴展為插入多列數據,只需要修改讀數據的地方和插入的SQL即可。


免責聲明!

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



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