【问题标题】:Extremely slow ResultSet next() performanceResultSet next() 性能极慢
【发布时间】:2016-08-10 05:54:14
【问题描述】:

我正在尝试从 oracle 数据库中获取一些结果,然后使用 jdbc 批处理将这些行插入到另一个 oracle 数据库中。但是 resultset.next() 的 while 循环非常慢。

选择查询包括 rowNum 和一些表连接。此外,其中还有 90 多列。我没有任何机会改进无法访问的查询。尽管如此,我认为这还不足以说明缓慢。这是不正常的,我找不到任何解决方案。

这是我的代码。当我注释掉所有代码时 在while 而不是counter++ 内部,仍然缓慢。所以我很确定问题的来源是sdResult.next()。您还可以在下面找到性能结果。

    try {
            ResultSet sdResult = sdbConnInstance.executeQuery(SOURCE_DB_QUERY1.toString());
            logger.info("bulkInsert started at: " + dateFormat.format(cal.getTime()));
            LinkedHashMap<String, String> columnMap = new LinkedHashMap<String, String>();
            ArrayList<LinkedHashMap> bulkList = new ArrayList<LinkedHashMap>();
            operationCleaned = true;
            int counter = 0;
            int countToBulkInsert = 0;
            while(sdResult.next()) {                                
                operationCleaned = false;
                counter++;
                for (int i = 0; i < SOURCE_DB_COLUMNS1_ARRAY.length; i++) {
                        String column = SOURCE_DB_COLUMNS1_ARRAY[i];
                        try {
                                columnMap.put(column, sdResult.getString(column));
                        } catch (Exception e) {
                                columnMap.put(column, null);
                        }

                }
                bulkList.add(columnMap);
                columnMap = new LinkedHashMap<String, String>();
                if (countToBulkInsert == BULK_INSERT_COUNT) {
                        tdbConnInstance.insertWithBatch(INSERT_QUERY_TEMPLATE.toString(), bulkList);
                        lEndTime = System.currentTimeMillis();
                        logger.info(countToBulkInsert + " rows are inserted in " + (lEndTime - lStartTime) + " ms. Total count=" + counter + ". New query is building...");
                        lStartTime = System.currentTimeMillis();
                        countToBulkInsert = 0;
                        bulkList = new ArrayList<LinkedHashMap>();
                        operationCleaned = true;
                }
            }
   } catch (Exception e) {
        e.printStackTrace();
        logger.error("Failed to insert!");
   }

如果我不使用 setFetchSize():

INFO:在 61804 毫秒内插入 100 行。总数=100。正在构建新查询...

INFO:在 94150 毫秒内插入 100 行。总计数=200。正在构建新查询...

INFO:在 61148 毫秒内插入 100 行。总数=300。正在构建新查询...

如果我将 setFetchSize(100) 与 PreparedStatement 一起使用:

INFO:在 62 毫秒内插入 100 行。总数=100。正在构建新查询...

INFO:在 60367 毫秒内插入 100 行。总计数=200。正在构建新查询...

INFO:在 64540 毫秒内插入 100 行。总数=300。正在构建新查询...

【问题讨论】:

  • 如果使用SQL客户端读取相同的数据需要多长时间?
  • 我正在使用 sql developer,大约需要 70 秒。
  • 那么它和你在Java中的一样,问题出在数据库服务器上。 Java 对此无能为力。
  • 不,我的意思是使用选择查询检索所有数据需要 70 秒。选择查询返回超过 80K 行。但是对于 100 行中的每一行,resultset.next 光标的移动花费了大约 60 秒。数据库插入、更新操作或数据结构操作比这快得多。
  • 抓取大小是多少。如果它是默认值,它可能非常小,因此每 10 行需要再次访问数据库

标签: java oracle jdbc resultset


【解决方案1】:

试试

 Resultset sdResult = sdbConnInstance.executeQuery(SOURCE_DB_QUERY1.toString());
sdResult.setFetchSize(100);

很快

将 100 更改为您的行大小。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-21
    • 2018-10-05
    • 1970-01-01
    • 2019-04-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多