【问题标题】:Running queries in parallel in Slick 3.x在 Slick 3.x 中并行运行查询
【发布时间】:2017-03-15 18:09:43
【问题描述】:

我在 Slick 3.x/Play for Scala 中有以下代码:

  val filters = TableQuery[FilterDB]
  val action6 = filters.filter(_.sk === sk).result
  val future6 = db.run(action6)
  Await.result(future6, Duration.Inf)

  val tags = TableQuery[TagSelectionDB]
  val action7 = tags.filter(_.sk === sk).result
  val future7 = db.run(action7)
  Await.result(future7, Duration.Inf)

请注意,这两个查询将按顺序运行。是否可以并行运行它们,如果可以,如何?此外,在 Scala/Slick 中并行运行的查询是否也会在数据库引擎中并行运行?

【问题讨论】:

  • 它们如何在 DB-Engine 中运行取决于 DB-Engine 本身。 You/Slick 无法控制。
  • 要并行运行这些,删除那些等待并使用 onCompletemap 等的未来。

标签: scala playframework slick playframework-2.5 slick-3.0


【解决方案1】:

是的。您可以并行运行查询,但它们在数据库中的运行方式无法由 slick 控制。数据库尝试尽可能地并行运行查询,除非存在任何数据依赖关系、在表和行上获取的锁等。这是完成这项工作的函数。

val f1 = db.run(action6)

val f2 = db.run(action7)

val result = f1 zip f2 

Await.result(result, Duration.Inf) // await only if you want to see the results in a blocking manner. Instead compose the future to produce results.

请注意,f1 和 f2 是并行运行的,因为它们是独立创建的。但是你必须等待结果future完成。

如果您有大量查询要执行,那么并行函数可以帮助您简化工作。

并行使用 Future.traverse 运行 db 查询的未来,并按顺序在列表中提供结果。

def parallely[T](dbios: DBIO[T]*): Future[List[Try[T]]] = {

 Future.traverse(dbios.map(db.run(_))) { f => 
  f.map(Success(_))
   .recover { case th => Failure(th)} }
}

用法:

val result = parallely(action6, action7)

//wait if you want to see the result in a blocking manner.
//Blocking is not good idea. So compose the resultant future to produce results based on db results.

【讨论】:

  • Here 它谈到在 Futures 中运行多个并行查询,这不应该是在 Slick 3.x 中工作的自然方式吗?另外,如何使用 map 或 flatMap 代替 zip?
猜你喜欢
  • 1970-01-01
  • 2015-09-19
  • 2018-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多