У меня есть запрос, который возвращает ~ 6000 строк. Мне нужно, чтобы все строки были возвращены, чтобы их можно было использовать для генерации R-скрипта, который выполняет пакетное задание. Мой метод выполнения запроса и итерации по ResultSet, заполняющему ArrayList, занимал 3 секунды (на что клиент пожаловался слишком медленно). Я сократил это значение до 0,7 секунды, выполнив начальный запрос, чтобы получить счетчик строк, а затем установив для параметра Fetch Size PreparedStatement это значение.
Старый (сокращенный) код:
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.
Мой вопрос заключается в том, существует ли более эффективный метод извлечения всех строк одновременно, чем выполнение дополнительного запроса для получения количества строк. Я не могу найти способ установить размер выборки на "все строки".