我有一个返回~6,000行的查询。我需要返回所有行,以便它们可以用于生成执行批处理作业的R脚本。我执行查询并迭代填充ArrayList的ResultSet的方法花了3秒钟(客户抱怨的速度太慢)。我通过运行初始查询得到行数,然后将PreparedStatement的Fetch Size设置为此计数,将其降低到0.7秒。
旧(精简)代码:
public List<MyClass> loadFromDb() {
try {
String sql = "SELECT a, b FROM table1, table2, LEFT JOIN table3...";
ResultSet result = connection.prepareStatement(sql).executeQuery();
List<MyClass> values = new ArrayList<>();
while (result.hasNext()) {
values.add(new MyClass(result.getString(1), result.getString(2)));
}
result.close();
return values;
} catch (SQLException e) {
e.printStackTrace();
return Collections.emptyList();
}
}
新代码:(注意我们现在可以将ArrayList初始化为所需的确切大小)
public List<MyClass> loadFromDb() {
try {
String sqlWithoutSelectClause = " FROM table1, table2, LEFT JOIN table3...";
int rowCount = getCount(sqlWithoutSelectClause);
String sql = "SELECT a, b" + sqlWithoutSelectClause;
PreparedStatement statement = connection.prepareStatement(sql);
statement.setFetchSize(rowCount);
ResultSet result = statement.executeQuery();
List<MyClass> values = new ArrayList<>(rowCount);
while (result.hasNext()) {
values.add(new MyClass(result.getString(1), result.getString(2)));
}
result.close();
return values;
} catch (SQLException e) {
e.printStackTrace();
return Collections.emptyList();
}
}
private int getCount(String sqlWithoutSelectClause) {
String sql = "SELECT COUNT(1) " + sqlWithoutSelectClause;
try {
ResultSet result = connection.prepareStatement(sql).executeQuery();
result.next();
int count = result.getInt(1);
result.close();
return count;
} catch (SQLException e) {
e.printStackTrace();
return 0;
}
}
我只使用JDBC,而不是Hibernate。我正在连接到Oracle数据库。
我的问题是,是否有一种更有效的方法可以一次获取所有行,而不是执行额外的查询来获取行数。我找不到将获取大小设置为“所有行”的方法。