我的任务是从SQL Server数据库中读取1500多万条记录,对它们执行一些处理,然后将结果写入平面文件。
如何使用Java有效地完成此操作?
我的初步想法是以块的形式查询数据,或者在执行查询时将结果流回来进行处理(如果可能的话)。
答案 0 :(得分:2)
看起来sql-server的jdbc驱动程序尊重fetchsize提示(它建议一次读取多少行),因此您应该能够发出一个查询并迭代结果集,处理和写入行你去的文件。 E.g:
public static void toFlat(Connection conn, File file, String destcode) {
PreparedStatement ps = null;
ResultSet rs = null;
BufferedWriter out = null;
try {
ps = conn.prepareStatement(
// col#: 1 2 3 4
"SELECT threatid, lastname, firstname, flightnum " +
"FROM travel.passengers " +
"JOIN threats.aliases USING (firstname, lastname) " +
"WHERE destination = ?" // param# 1
);
ps.setString(1,destcode); // param# 1
out = new BufferedWriter(new FileWriter(file));
// provides hint for driver to load x rows at a time:
ps.setFetchSize(1000);
ps.executeQuery();
rs = ps.getResultSet();
while(rs.next()) {
Integer threatid = rs.getInt(1);
String lastname = rs.getString(2);
String firstname = rs.getString(3);
Integer flightnum = rs.getInt(4);
//rubber meets road:
String row = processRow(threatid, lastname, firstname, flightnum);
out.write(row);
}
} catch(SQLException e) {
// TODO
} catch (IOException e) {
// TODO
e.printStackTrace();
} finally {
try {
ps.close();
} catch(Exception e){
//TODO
}
try {
rs.close();
} catch(Exception e){
//TODO
}
try {
out.close();
} catch(Exception e){
//TODO
}
}
}
答案 1 :(得分:2)
如果有效仅与阅读相关,则有关获取大小的答案是可行的方法。如果您在数据库主机(=> localhost连接)上运行Java程序,它将为您提供性能提升。
如果高效也适用于处理,请在SQL查询中尽可能多地执行此操作。我们运行测量,RDBMS优于Java。例如,Java中的过滤和排序需要更长的时间。
再次在Java中重新实现数据库功能毫无意义。如果使用SQL查询不容易实现算法,请在存储过程中执行其他(过程)处理,将其完全写为存储过程或在SQL查询中使用存储函数。将存储的函数与SQL查询一起使用是一种非常强大且快速的组合。 您的Java客户端只读取结果,并将它们直接写入磁盘。没有缓冲,没有处理,只有I / O.
如果您使用的是Oracle,PostgreSql或DB2,您甚至可以用Java编写存储过程/函数。