14

滑らかなストリーミングを操作する方法を理解しようとしています。postgresドライバーでslick 3.0.0を使用しています

状況は次のとおりです。サーバーは、サイズ(バイト単位)で制限されたチャンクに分割されたデータのシーケンスをクライアントに提供する必要があります。だから、私は次の洗練されたクエリを書きました:

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、 custom を書きPushPullStageました。これは、データのサイズ (バイト単位) を制限し、サイズ制限に達したときにアップストリームを終了します。それはうまく動作します。問題は、postgres のログを調べると、そのようなクエリが表示されることです。 select * from sequences where user_id = 0 and timestamp > 0 order by timestamp;

そのため、一見すると、各クエリで数バイトを使用するだけで、多くの (そして不必要な) データベース クエリが実行されているように見えます。データベースのクエリを最小限に抑え、各クエリで転送されるデータを最大限に活用するために、Slick でストリーミングを行う正しい方法は何ですか?

4

2 に答える 2

18

Slick と Postgres でストリーミングを行う「正しい方法」には、次の 3 つが含まれます。

  1. db.stream() を使用する必要があります

  2. autoCommitJDBC ドライバーで無効にする必要があります。1 つの方法は、接尾辞 を付けて、クエリをトランザクションで実行すること.transactionallyです。

  3. fetchSize0 以外に設定する必要があります。そうしないと、postgres が resultSet 全体を一度にクライアントにプッシュします。

元:

DB.stream(
  find(0L, 0L)
    .transactionally
    .withStatementParameters(fetchSize = 1000)
).foreach(println)

便利なリンク:

https://github.com/slick/slick/issues/1038

https://github.com/slick/slick/issues/809

于 2015-07-12T18:58:11.327 に答える