我在课堂上有以下方法:
public void insertShingleSets(Vector<ShingleSet> shingleSets)
{
String sql = "INSERT INTO tblPostingsShingles("+
"rowId, " +
"shingle) " +
"VALUES(?,?);";
PreparedStatement statement = null;
try {
statement = conn.prepareStatement(sql);
for (int i = 0; i < shingleSets.size(); i++)
{ String id = shingleSets.get(i).getRowId();
String shingle = shingleSets.get(i).getShingle();
statement.setInt(1, Integer.parseInt(id));
statement.setString(2, shingle);
statement.addBatch();
if ((i + 1) % 1000 == 0) {
System.out.println("doing a batch " + i); //-------------
statement.executeBatch(); // Execute every 1000 items.
System.out.println("done batch " + i); //-------------
}
}
statement.executeBatch();
}
catch (SQLException ex)
{
// handle any errors
System.out.println("SQLException: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
}
finally {
if (statement != null)
try { statement.close();
} catch (SQLException logOrIgnore) {}
if (conn != null)
try { conn.close();
} catch (SQLException logOrIgnore) {}
}
}
执行之间的时间:System.out.println(“做批处理”+ i); 并执行:System.out.println(“done batch”+ i); 考虑到它只将两列插入三列表(另一列是自动编号主键,并且在启动/测试时表中没有行),这似乎相当多了30秒。 我唯一能想到的是,在调用此方法之前,另一种方法使用查询表tblPostingsShingles来检查某些rowId是否存在。但是,我认为当该方法完成时会释放任何锁(它具有与此方法相同的finally子句)。 任何建议将不胜感激。 戴夫
答案 0 :(得分:1)
你可以试验批量大小,但是我的流程看起来非常快,每批500个,而且1000不是太大 - 没有明显的理由我可以看到这需要这么长时间 - 这很容易就是一个订单太慢了。
其他可能的性能瓶颈是您的mysql配置和网络连接速度。这种速度是否比一次写一次更快?
答案 1 :(得分:0)
我建议尝试使用较小的批量大小。通常,当我进行批量插入时,我一次将大小限制为20-50行。现在有1000行批处理,您的工作可能会阻塞数据库和网络I / O.如果减少批量大小,您可以加快处理速度。