仅当语句返回LONG列时才会发生这种情况。
即使我不执行任何操作,例如rs.getString,也只需执行即可。


  sql1:那是:7593毫秒sql2:那是:530毫秒


如您所见,这与数据量无关。
当我使用OracleConnection:OracleStatement:OracleCachedResultSet时,结果是相同的。
我也尝试使用OracleCachedRowSet而不是ResultSet。
问题出现在OracleCachedRowSet.next()之前的OracleCachedRowSet.execute()中。
当我设置setFetchSize(1)时:


  sql1:那是:7474毫秒sql2:那是:7153毫秒


更新1:
我测试了其他工具:


  sql1#Toad For Oracle:执行时间  sql1#Oracle SQL Developer精简:7.5秒(与我的结果相同)
  sql1#Oracle SQL Developer OCI:7.5秒(与我的结果相同)
  sql2#Oracle SQL Developer精简版:0.36秒(与我的结果相同)
  在Java应用程序中,在sql1情况下,行一一对应。因此,看起来setFetchSize()无效。


样例代码:

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(在我使用11.2.0.2捆绑包中的ojdbc6.jar之前)和OracleJDBCRowSet的结果。
19行:


  sql1:那是:1470 ms // 7-8秒之前
  sql2:那是:1140毫秒


99行


  sql1:那是:1491毫秒
  sql2:那是:1158毫秒


如您所见,它的查询速度要快得多,但仍然比查询更多数据的查询速度慢。
添加更多列几乎不会改变执行和获取时间,因此该问题已部分解决。
但是似乎这些改进仅适用于RowSet。
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());
        }
    }
}

09-27 02:32