2016-05-31 66 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' –