优化数据库插入java
我对Java和数据库相对较新,因此请求您帮助我进行代码优化。我有大约20个文本文件,逗号分隔值。每个文本文件大约有10000行基于每行的第3个值,我将数据插入到不同的表中。每次我检查第三个值并使用不同的方法来保存这些数据。我的代码如下。有人可以告诉我,这是否是正确的方式来执行此操作。 在此先感谢。优化数据库插入java
public void readSave() throws SQLException
{
File dir = new File("C:\\Users\\log");
String url = Config.DB_URL;
String user= Config.DB_USERNAME;
String password= Config.DB_PASSWORD;
con= DriverManager.getConnection(url, user, password);
con.setAutoCommit(false);
String currentLine;
if (!dir.isDirectory())
throw new IllegalStateException();
for (File file : dir.listFiles()) {
BufferedReader br;
try {
br = new BufferedReader(new FileReader(file));
while ((currentLine = br.readLine()) != null) {
List<String> values = Arrays.asList(currentLine.split(","));
if (values.get(2).contentEquals("0051"))
save0051(values,con);
else if(values.get(2).contentEquals("0049"))
save0049(values,con);
else if(values.get(2).contentEquals("0021"))
save0021(values,con);
else if(values.get(2).contentEquals("0089"))
save0089(values,con);
if(statement!=null)
statement.executeBatch();
}
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
con.commit();
statement.close();
con.close();
}
catch (Exception e) {}
}
private void save0051(List<String> values, Connection connection) throws SQLException {
// TODO Auto-generated method stub
String WRITE_DATA = "INSERT INTO LOCATION_DATA"
+ "(loc_id, timestamp, message_id" +
) VALUES (?,?,?)";
try {
statement = connection.prepareStatement(WRITE_DATA);
statement.setString(1, values.get(0));
statement.setLong(2, Long.valueOf(values.get(1)));
statement.setInt(3, Integer.valueOf(values.get(2)));
statement.addBatch();
} catch (SQLException e) {
e.printStackTrace();
System.out.println("Could not save to DB, error: " + e.getMessage());
}
return;
}
- 不要建立在循环的数据库连接。这是一项昂贵的操作,您只应创建一次。
- 不要在循环中创建
PreparedStatement
。创建一次并重用它。 - 不要在每个INSERT后提交。 Read about using batches for inserting。这大大降低了“提交开销”,如果你只提交一个提交数据,比如200个INSERT。
我需要4 4个不同的表的不同PreparedStatements? – 2013-05-03 07:00:58
@ user2236033是的,你这样做是因为表名是在准备语句中编译的,只有值是可变的。 – Kai 2013-05-03 07:38:07
如果这将是性能至关重要,我会建议一些更改。
- 将连接创建移出循环,您不希望这样做成千上万次。
- 由于每个函数都重复进行相同的查询,因此可以缓存PreparedStatements,并重复执行它们,而不是在每个查询中重新创建它们。这样数据库将只需要优化一次查询,并且每个查询将只传输查询的数据,而不是整个查询和数据。
感谢您的发贴 – 2013-05-02 13:27:21
没问题。然而,我会留意@ user714965关于批量插入的建议。这是明智的做法。事实上,我会进一步说,你应该检查你是否真的需要交易,如果你不需要它,只需删除交易相关的代码。 最后,如果您确实需要这个,并且您正在对生产数据库运行它,那么对插入进行速率限制可能是一个好主意,因此您不会因高写入工作量而抛弃数据库。 – 2013-05-02 13:31:03
感谢您的更新。正如所建议的,我移动了连接创建和 – 2013-05-03 06:16:41
看来你正准备在每个函数调用语句,会更好,如果你准备他们一次,用不同的语句对象的名字,只是访问了它们在varous功能 – Akash 2013-05-02 13:14:05