通过jdbc获取Oracle DB LONG类型非常慢

时间:2014-11-12 08:07:17

标签: java oracle jdbc

仅当语句返回 LONG 列时才会发生这种情况 即使我没有对它做任何事情,比如 rs.getString ,只需执行。

  

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

正如您所看到的,它与数据量无关 当我使用 OracleConnection时:OracleStatement:OracleCachedResultSet 结果是一样的。
我还尝试使用 OracleCachedRowSet 而不是 ResultSet
OracleCachedRowSet.next()之前,问题出现在 OracleCachedRowSet.execute()中。
当我设置 setFetchSize(1)

  

sql1:那是:7474 ms
sql2:那是:7153 ms

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

  

sql1# Toad For Oracle:执行时间< 1秒
   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");
    } 
}

1 个答案:

答案 0 :(得分:1)

ojdbc7.jar 的结果(在我使用11.2.0.2捆绑包中的 ojdbc6.jar 之前)和 OracleJDBCRowSet 之前。
19行:

  

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

99行:

  

sql1:那是:1491 ms
   sql2:那是:1158 ms

正如你可以看到它更快,但仍然比查询更慢的数据更慢 添加更多列几乎不会改变执行和获取时间,因此问题部分得到解决 但似乎只是改进了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());
        }
    }
}