当前位置: 首页 > 知识库问答 >
问题:

在java中并行读取/处理结果集

符学
2023-03-14

我需要迭代resultset中返回的数百万条记录,并对它们进行处理,然后将它们存储在某些数据结构中。我没有找到任何相关的例子或参考。JOOQ似乎在做一些我可能想要的事情,但它似乎不是免费的。我希望,如果使用Java8流,我可能能够实现它,但示例或writeup似乎没有给我任何方向。我也愿意接受其他选择
基于这个SO参考:resultset parallel,我在下面进行了尝试,但它没有给我任何性能改进,如下面的性能指标所示
代码:顺序迭代:

while(rs.next()) {
    System.out.println(rs.getString(1));
    }

使用流和分裂器:

Stream<String> s = StreamSupport.stream(new Spliterators.AbstractSpliterator<String>(Long.MAX_VALUE,
                Spliterator.ORDERED) {

            @Override
            public boolean tryAdvance(Consumer<? super String> action) {
                try {
                    if (!rs.next())
                        return false;
                    action.accept(rs.getString(1));
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                return true;
            }
        }, true);
        s.forEach(System.out::println);

记录总数:3759
连续记录占用的时间:~83.8秒
流占用的时间:~83.5秒

有谁能回顾一下,告诉我我是否没有正确地实现流。

共有1个答案

顾兴昌
2023-03-14

无法并行处理结果集。它是一种迭代器,合并了必须为查询更改的可变状态,最显著的是,ResultSet有一个当前行,在读取之前必须将其移动到该行。即使对于通过索引访问的行中的值,该规范也没有提供线程安全保证,并提到底层数据库可能不支持无序读取它们。

因此,可以从并行处理中获益的唯一操作是链式后续操作,但当唯一链式操作是系统时。out::println,你让事情变得更糟。打印操作不仅不能从并行处理中获益,而且所有标准实现在系统中都有PrintStream。输出,将每个写入操作同步到目标输出。

请注意,即使您链接计算密集型操作(这可能会从并行处理中受益),也有可能昂贵的数据库操作支配了整个执行时间。这就是为什么在将数据传输到Java端之前,让数据库尽可能多地过滤和/或聚合数据是很重要的…

 类似资料:
  • 我看到了很多关于从异步任务中获取结果的问题,但没有一个解决了我的问题。我想做的是从MyClass对象的异步任务数组中获取并在UI中使用它们,但在不同的情况下我有不同的UI。有时我用我的数组填充recyclerview,有时我用我的数组填充无尽的选项卡活动。这意味着我不能将UI元素传递给异步任务,以便在中处理它。我想从异步任务中得到的结果正是MyClass对象的数组,然后在不同的情况下以不同的方式使

  • 问题内容: 我想执行匿名PL / SQL,并需要获取结果集对象。我得到了可以通过使用PL / SQL块内的游标完成的代码。 但是PL / SQL块本身将以文本形式来自数据库。因此,我无法编辑该PL / SQL块。并且它将仅返回两个其列名始终相同的值。它将返回2个列组合值的列表。 在这里,我给出示例PL / SQL。 任何回复都将非常有帮助。 问题答案: 这是一个如何“执行匿名PL / SQL并获取

  • QueryList返回的集合数据均为Collection集合对象而非普通数组,目的就是为了方便处理采集结果数据。 QueryList引入了Laravel中Collection集合对象,它提供了一个更具可读性的、更便于处理数组数据的封装。下面通过几个例子来说明它的用法,更多用法可以去查看Laravel文档。 Collection文档:https://d.laravel-china.org/docs/

  • 问题内容: 为什么下面的代码不输出任何输出,而如果我们删除parallel,则输出0、1? 尽管我知道理想情况下应该将限制放在不同的位置,但是我的问题与添加并行处理导致的差异更多有关。 问题答案: 真正的原因是 有序并行 是完整的屏障操作,如文档中所述: 保持并行管道的稳定性是相对昂贵的(要求操作充当一个完整的屏障,并具有大量缓冲开销),并且通常不需要稳定性。 “完全屏障操作”是指必须先执行所有上

  • 当我使用Spring批处理管理运行长时间运行的批处理作业的多个实例时,它会在达到jobLauncher线程池任务执行程序池大小后阻止其他作业运行。但是从cron中提取多个工作似乎效果不错。下面是作业启动器配置。 Spring批处理管理员Restful API是否使用不同于xml配置中指定的作业启动器?