我正在使用Scala。
我尝试从大约400万行的表中获取所有数据。我使用了流,代码就像
val stream Stream[Record] = expression.stream().iterator().asScala.toStream
stream.map(println(_))
表达是Jooq中的SelectFinalStep [Record]。
然而,第一行太慢了。它需要几分钟。我做错了吗?
答案 0 :(得分:2)
如果您使用的是Scala 2.12,则不必将expression.stream()
返回的Java流转换为Scala Iterator
,然后转换为Scala Stream
。只需致电:
expression.stream().forEach(println);
虽然jOOQ的ResultQuery.stream()
方法创建了一个懒惰的Java 8 Stream
,它在消费后再次被丢弃,但Scala的Stream
会将先前获取的记录保留在内存中以便重新遍历。在获取400万条记录时,这可能是造成大多数性能问题的原因。
请注意expression.stream()
会返回一个资源丰富的流,保持一个开放的基础ResultSet
和PreparedStatement
。也许,在消费后明确关闭流是个好主意。
此外,您可能希望调用调用expression.fetchSize()
的Statement.setFetchSize()
来调用JDBC的{{3}}。这允许JDBC驱动程序获取N行批次。某些JDBC驱动程序默认使用合理的提取大小,其他驱动程序默认在将所有行传递到内存之前将其提取到内存中。
答案 1 :(得分:0)
另一种解决方案是延迟获取记录并构造一个scala流。例如:
def allRecords():Stream[Record] = {
val cur = expression.fetchLazy()
def inner(): Stream[Record] = {
if(cur.hasNext) {
val next = cur.fetchOne
next #:: inner()
}
else
Stream.empty
}
inner()
}