Это происходит только тогда, когда оператор возвращает столбец LONG.
Даже если я ничего не делаю с ним, например rs.getString, просто выполните.
sql1: Это было: 7593 мс
sql2: Это было: 530 мс
Как вы можете видеть, это не объем данных.
Когда я использую OracleConnection: результат OracleStatement: OracleCachedResultSet тот же.
Также я попытался использовать OracleCachedRowSet вместо ResultSet.
Проблема появляется в OracleCachedRowSet.execute() перед OracleCachedRowSet.next().
Когда я устанавливаю setFetchSize (1):
sql1: Это было: 7474 мс
sql2: Это было: 7153 мс
ОБНОВЛЕНИЕ 1:
Я тестировал другие инструменты:
sql1 # Жаба для Oracle: время выполнения <1 секунда
sql1 # Oracle SQL Developer тонкий: 7,5 секунды (то же, что и мой результат)
sql1 # Oracle SQL Developer OCI: 7.5 секунд (так же, как и мой результат)
sql2 # Oracle SQL Developer тонкий: 0,36 секунды (то же, что и мой результат)
Строки, введенные один за другим в случае sql1 в java-приложении, так выглядят как setFetchSize() dosn't work.
Образец кода:
public class Test {
public static void main(String[] args) throws SQLException {
final String sql1 = "select HIGH_VALUE from sys.DBA_TAB_PARTITIONS WHERE rownum < 20";
final String sql2 = "select PARTITION_NAME, HIGH_VALUE_LENGTH,TABLESPACE_NAME,NUM_ROWS,BLOCKS,\n"
+ "EMPTY_BLOCKS,LAST_ANALYZED,AVG_SPACE,SUBPARTITION_COUNT,COMPRESSION from sys.DBA_TAB_PARTITIONS WHERE rownum < 20";
OracleDataSource ods = new OracleDataSource();
ods.setDriverType("thin");
ods.setUser("vr");
ods.setPassword("oracle");
ods.setDatabaseName("ORCL");
ods.setServerName("192.172.18.1");
ods.setPortNumber(1521);
Connection conn = null;
conn = ods.getConnection();
Statement stmt = conn.createStatement();
stmt.setFetchSize(1000);
// Start time
long startTime = System.currentTimeMillis();
ResultSet rs = stmt.executeQuery(sql1);
rs.setFetchSize(1000);
while (rs.next()){
//System.out.println(rs.getString(1) + " " + rs.getString(2));
System.out.println("row#: " + rs.getRow());
}
// Finish time
long endTime = System.currentTimeMillis();
System.out.println("That was: " + (endTime - startTime) + " ms");
}
}
Результаты с новым ojdbc7.jar (до того, как я использовал ojdbc6.jar из пакета 11.2.0.2) и OracleJDBCRowSet.
19 строк:
sql1: Это было: 1470 мс//до 7-8 секунд
sql2: Это было: 1140 мс
99 строк:
sql1: Это было: 1491 мс
sql2: Это было: 1158 мс
Как вы можете видеть, это намного быстрее, но все же медленнее, чем запрос с еще большим количеством данных.
Добавление большего количества столбцов почти не вносит изменений в выполнение и выбор времени, поэтому проблема частично решена.
Но кажется, что улучшения приходят только в RowSets.
OracleResultSet все еще работает очень медленно.
Также, если вы связываете новый драйвер с Oracle SQL Developer, это не имеет никакого эффекта.
Образец кода:
public class Test {
public static void main(String[] args) {
final String sql1 = "select HIGH_VALUE from sys.DBA_TAB_PARTITIONS WHERE rownum < 100";
final String sql2 = "select PARTITION_NAME, HIGH_VALUE_LENGTH,TABLESPACE_NAME,NUM_ROWS,BLOCKS,\n"
+ "EMPTY_BLOCKS,LAST_ANALYZED,AVG_SPACE,SUBPARTITION_COUNT,COMPRESSION "
+ "from sys.DBA_TAB_PARTITIONS WHERE rownum < 100";
OracleDataSource ods = null;
try {
ods = new OracleDataSource();
} catch (SQLException ex) {
System.exit(2);
}
ods.setDriverType("thin");
ods.setUser("vr");
ods.setPassword("oracle");
ods.setDatabaseName("ORCL");
ods.setServerName("192.172.18.1");
ods.setPortNumber(1521);
try (Connection conn = ods.getConnection();) {
try (OracleJDBCRowSet rs = new OracleJDBCRowSet(conn);) {
rs.setFetchSize(200);
rs.setReadOnly(true);
rs.setCommand(sql2);
// Start time
long startTime = System.currentTimeMillis();
rs.execute();
while (rs.next()) {
System.out.println("row#: " + rs.getRow() + " " + rs.getString(1));
}
// Finish time
long endTime = System.currentTimeMillis();
System.out.println("That was: " + (endTime - startTime) + " ms");
}
} catch (SQLException e) {
System.err.println(e.getMessage());
}
}
}