我希望能够使用 Slick 从一个非常大的表中获取所有记录。如果我尝试通过 foreach、for 或列表获取来做到这一点;我收到内存不足异常。
有什么方法可以将“游标”与 Slick 或延迟加载一起使用,只在需要时获取对象以减少使用的内存量?
不确定游标是什么意思,但您可以使用分页获取部分数据:
query.drop(0).take(1000) will take the first 1000 records
query.drop(1000).take(1000) will take from 1001 to 2000 lines of the table.
但是这个查询效率将取决于你的数据库,如果它支持它,如果表是正确的索引。
您可以使用iterator
返回迭代器的组合:
val object = Objects.where(...).map(w => w).iterator()
和一个groupby:
val chunkSize = 1000
val groupedObjects = objects.grouped(chunkSize)
groupedObjects.foreach {objects => objects.par.map(h => doJob(h))}
正如这个答案中所建议的
dirceusemighini 的回答是正确的。由于对 Query.list() 的错误假设,几天前我遇到了类似的问题,所以我可以提供更多上下文。来自 Slick 参考:
“查询是使用 Invoker trait(或无参数版本的 UnitInvoker)中定义的方法执行的。Query 有一个隐式转换,因此您可以直接执行任何 Query。最常见的使用场景是将完整的结果集读入严格的使用特殊方法(例如列表)或可以构建任何类型集合的通用方法的集合”
Query.list() 确实将完整的结果集加载到内存中。考虑到这一点,您可以有多种方法来解决您的问题。