Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Inserção ou atualização em massa Slick 3.0 (upsert)


Existem várias maneiras de tornar este código mais rápido (cada uma deve ser mais rápido que os anteriores, mas fica progressivamente menos idiomático):

  • Execute insertOrUpdateAll em vez de insertOrUpdate se estiver em slick-pg 0.16.1+
    await(run(TableQuery[FooTable].insertOrUpdateAll rows)).sum
    

  • Execute seus eventos DBIO todos de uma vez, em vez de esperar que cada um seja confirmado antes de executar o próximo:
    val toBeInserted = rows.map { row => TableQuery[FooTable].insertOrUpdate(row) }
    val inOneGo = DBIO.sequence(toBeInserted)
    val dbioFuture = run(inOneGo)
    // Optionally, you can add a `.transactionally`
    // and / or `.withPinnedSession` here to pin all of these upserts
    // to the same transaction / connection
    // which *may* get you a little more speed:
    // val dbioFuture = run(inOneGo.transactionally)
    val rowsInserted = await(dbioFuture).sum
    

  • Desça para o nível JDBC e execute seu upsert de uma só vez (ideia através desta resposta ):
    val SQL = """INSERT INTO table (a,b,c) VALUES (?, ?, ?)
    ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);"""
    
    SimpleDBIO[List[Int]] { session =>
      val statement = session.connection.prepareStatement(SQL)
      rows.map { row =>
        statement.setInt(1, row.a)
        statement.setInt(2, row.b)
        statement.setInt(3, row.c)
        statement.addBatch()
      }
      statement.executeBatch()
    }