Slick 3-upsert работает слишком медленно


Я использую текущий код для upsert списка items

case class Item(id: String, text: String)

class Items(tag: Tag) extends Table[Item](tag, "items"){
    ...
}

val tbl = TableQuery[Items]

def insertItems(items: List[Item]):Future[Int] = {
    val q = DBIO.sequence(items.map(tbl.insertOrUpdate).toSeq).map(_.sum)
    db.run(q)
}

Для items списка длиной 2000, upsert занимает ~10 секунд. Это слишком долго...

Я думаю, что большую часть времени занимает компиляция запросов.

Как я должен переписать insertItems для ускорения его?

1 4

1 ответ:

Использование compiled queries( docs ). AFAIK, скомпилированные запросы для вставки доступны после slick 2.0.

Кроме того, чтобы вставить список, вы должны выполнить пакетную операцию, а не вставлять запись по одному.

Итак, в Slick-3.0, для вставки, вы должны сделать:

val tblCompiled = Compiled(TableQuery[Items])
tblCompiled ++= items

Затем выполните другой запрос, чтобы получить сумму нужного столбца.

EDIT: я не думаю, что slick поддерживает инструкции bulk insertOrUpdate. Если базовая БД поддерживает bulk insertOrUpdate, то самый быстрый подход будет заключаться в написании простого SQL. В противном случае скомпилированный insertOrUpdate запрос должен быть прилично быстрым.

Код должен быть примерно таким:

items.map(tblCompiled.insertOrUpdate)