使用slick的3.0.0流媒体结果和Postgresql的正确方法是什么?

使用slick的3.0.0流媒体结果和Postgresql的正确方法是什么?,postgresql,scala,slick,slick-3.0,akka-stream,Postgresql,Scala,Slick,Slick 3.0,Akka Stream,我正在尝试找出如何使用slick流媒体。我使用slick 3.0.0和postgres驱动程序 情况如下:服务器必须将客户机的数据序列分割成大小受限的数据块。所以,我写了以下巧妙的查询: val sequences = TableQuery[Sequences] def find(userId: Long, timestamp: Long) = sequences.filter(s ⇒ s.userId === userId && s.timestamp > timesta

我正在尝试找出如何使用slick流媒体。我使用slick 3.0.0和postgres驱动程序

情况如下:服务器必须将客户机的数据序列分割成大小受限的数据块。所以,我写了以下巧妙的查询:

val sequences = TableQuery[Sequences]
def find(userId: Long, timestamp: Long) = sequences.filter(s ⇒ s.userId === userId && s.timestamp > timestamp).sortBy(_.timestamp.asc).result
val seq = db.stream(find(0L, 0L))
我将seq和akka streams Source结合起来,编写了自定义PushPullStage,它以字节为单位限制数据的大小,并在达到大小限制时完成上游。它很好用。问题是——当我查看postgres日志时,我看到这样的查询 从user_id=0且timestamp>0的序列中按时间戳顺序选择*


因此,乍一看,似乎有很多不必要的数据库查询正在进行,每次查询只使用几个字节。使用Slick进行流式处理的正确方法是什么,以最大限度地减少数据库查询并充分利用每个查询中传输的数据?

使用Slick和Postgres进行流式处理的正确方法包括三件事:

必须使用db.stream

必须在JDBC驱动程序中禁用自动提交。一种方法是通过后缀.transactionaly使查询在事务中运行

必须将fetchSize设置为0以外的值,否则postgres将一次性将整个结果集推送到客户端

例:

有用链接:


正确的流入滑溜的方法如文件所示

val q = for (c <- coffees) yield c.image
val a = q.result
val p1: DatabasePublisher[Blob] = db.stream(a.withStatementParameters(rsType = ResultSetType.ForwardOnly, rsConcurrency = ResultSetConcurrency.ReadOnly, fetchSize = 1000 /*your fetching size*/).transactionally)

谢谢你的回答,非常有帮助。我对附录感到困惑:处理数据库的执行上下文不是在AsyncExecutor中单独维护的吗?很好!关于附录:是的,你是对的。它应该是默认值。我删除了附录,因为它混淆了更多,而不是帮助,事后看来,我想它真的与背压力学有关。我的消费者比网络快得多,所以在结果到达时尽快处理期货是一个更合适的解决方案。MySQL有没有类似的解决方案?为什么实际上禁用自动提交?
val q = for (c <- coffees) yield c.image
val a = q.result
val p1: DatabasePublisher[Blob] = db.stream(a.withStatementParameters(rsType = ResultSetType.ForwardOnly, rsConcurrency = ResultSetConcurrency.ReadOnly, fetchSize = 1000 /*your fetching size*/).transactionally)