2016-05-31 50 views
1

目前我們正在從一個database中選擇數據並將其插入備份數據庫(SQL SERVER)。插入性能調優

該數據在一次選擇中總是包含超過15K條記錄。 我們使用枚舉遍歷所選的數據。

我們正在使用JDBC PreparedStatement插入數據:

Enumeration values = ht.elements(); -- ht is HashTable containing selected data. 
     while(values.hasMoreElements()) 
     { 
       pstmt = conn.prepareStatement("insert query"); 
          pstmt.executeUpdate(); 
     } 

我不知道這是否是做的更快插入正確的或有效的方法。

對於插入10k行需要約30分鐘或更長的時間。 有沒有什麼有效的方法讓它變快?
注意:不使用表上的任何索引。

+3

考慮用'PreparedStatement'進行批處理,並確保autocommit已關閉。 – Kayaman

+0

您在這裏使用Oracle和MS SQL Server嗎? – jarlh

+0

目標表不應該有任何索引。這將有助於更快插入。 –

回答

1

使用批量插入,但也有少數entris後提交,不要試圖一次發送的所有10K。嘗試調查以獲得最佳尺寸,這是對內存和網絡旅行的折衷。

Connection connection = new getConnection(); 
Statement statement = connection.createStatement(); 
int i = 0; 

for (String query : queries) { 
    statement.addBatch("insert query"); 
    if ((i++ % 500) == 0) { 
     // Do an execute now and again, don't send too many at once 
     statement.executeBatch(); 
    } 
} 

statement.executeBatch(); 
statement.close(); 
connection.close(); 

此外,從你的代碼,我不知道你在做什麼,而是用paramaterised查詢,而不是發送10K插入語句爲文本。喜歡的東西:

String q= "INSERT INTO data_table (id) values (?)"; 
Connection connection = new getConnection(); 
PreparedStatement ps = connection.prepareStatement(q); 

for (Data d: data) {  
    ps.setString(1, d.getId()); 
    ps.addBatch(); 
} 

ps.executeBatch(); 
ps.close(); 
connection.close(); 
+0

謝謝,我使用插入語句作爲文本,正在使用參數化查詢將使其效率?關於批量插入「查詢」你的意思是說,因爲我在循環中使用單個插入查詢? – nilFi

+0

是的,一個參數化的查詢將會更有效率,因爲查詢每批次只發送一次,這將使得發送的有效載荷更小。另外,數據庫服務器不需要分別解析每個查詢。 – vickirk

1

您可以在一個SQL命令插入所有的值:

INSERT INTO Table1 (Column1, Column2) VALUES 
(V1, V2), (V3, V4), ....... 

您也可以通過500個記錄散貨插入值,例如,如果查詢將變得非常大。根據語句遠程插入行(使用連接)效率不高。另一種解決方案是使用存儲過程執行插入操作。您只需將值作爲參數傳遞給它。

這裏是如何使用上述INSERT命令做到這一點:

Enumeration values = ht.elements(); -- ht is HashTable containing selected data. 
int i=0; 
String sql=""; 

    while(values.hasMoreElements()) 
    { 
      sql+="(" + values + ")"; //better use StringBuffer here 
      i++; 
      if(i % 500 == 0) { 
       pstmt = conn.prepareStatement("insert query "+sql); 
       pstmt.executeUpdate(); 
       sql=""; 
      } 
      else 
       sql += " , "; 
    } 
+0

我正在使用插入查詢完全符合你的建議。我們如何使用批量插入? Plz建議 – nilFi

+0

請記住,此方法在插入語句中具有1000個值的限制。 –

+1

@nilFi我更新了答案。簡而言之,您爲每個500條記錄創建一個插入語句並執行它。 – AhmadWabbi

1

你可以做最簡單的事情是用一個單一的交易所有INSERT聲明:

Enumeration values = ht.elements(); -- ht is HashTable containing selected data. 

    conn.CallMethodForBeginTx(); 

    while(values.hasMoreElements()) 
    { 
      pstmt = conn.prepareStatement("insert query"); 
         pstmt.executeUpdate(); 
    } 

    conn.CallMethodForCommitTx(); 

,也不要忘了來管理SQL異常(conn.CallMethodForRollbackTx();

here描述了這兩種方法之間的性能差異。

如果表現仍然是問題,請回復。

+0

SQL Server用於dev和prod的版本是什麼? 'SELECT @@ VERSION' –