DBClients推荐的处理大量行的方法是什么?
我目前在返回多个执行()的DbStatement上使用DbStatement API。这是将整个宇宙下载到JVM内存中,还是在内部分批进行流?如果它正在分页/批处理结果集,那么是否应该使用一些API来提示获取大小?
--
jOOQ公开Settings.setFetchSize以全局提示所有jOOQ查询的获取大小,我认为它直接绑定到JDBC语句的setFetchSize API。
DBClient有类似的设置吗?
发布于 2022-11-17 05:54:18
DBClient不公开任何API来调整语句和结果集上的JDBC。因此,这都取决于底层DB驱动程序的实现。
如果我深入挖掘,这不仅仅是设置fetchSize。内存特性更多地取决于您如何使用来自DBExecutor的返回值,而不是DBClient如何在内部管理其结果集。
多个实现Flow.Publisher,因此根据订阅者的请求响应处理结果集。在内部,DBClient发布服务器在ResultSet上迭代,在每一行上调用onNext()。
现在,这一切都归结为返回的行在下游被消耗。
dbClient.execute(
dbExecute -> dbExecute.createQuery(sql).execute()
).map(dbRow -> <doSomething>)上面的示例是安全的,并且不会导致线性内存的积累,只要操作符都是中间的,并且只对传递的项进行操作。
但使用终端运营商,如:
dbClient.execute(dbExecute -> dbExecute.createQuery(sql).execute())
.map(dbRow -> <doSomething>)
.collectList()很明显,当它终止时,内存就会被吹灭,从而导致一个集合。因此,在上述情况下,DBClient不是一个因素,而是下游操作符。
从OJDBC中,它看起来是默认的fetchSize是10行,但这是一个没有意义的情况。
发布于 2022-11-17 20:29:21
如上所述,这取决于终端操作,也取决于doSomething所做的工作。如果doSomething同步处理每一行,那么您就会得到背压,并且不会无限制地消耗资源。另一方面,如果doSomething异步完成这项工作(通过将其转储到线程池或添加到队列中),那么您就有可能耗尽资源。
如果终端操作是subscribe(),那么用户代码就可以完全控制背压,可以通过使用Subscription.request()测量数据来异步完成这项工作。
https://stackoverflow.com/questions/74464939
复制相似问题