sql >> Databasteknik >  >> RDS >> Mysql

Slick 3.0 bulk infoga eller uppdatera (upsert)

Det finns flera sätt att göra den här koden snabbare (var och en bör). vara snabbare än de föregående, men det blir successivt mindre idiomatiskt:

  • Kör insertOrUpdateAll istället för insertOrUpdate om på slick-pg 0.16.1+

    await(run(TableQuery[FooTable].insertOrUpdateAll rows)).sum
    
  • Kör dina DBIO-event på en gång, istället för att vänta på att var och en ska begås innan du kör nästa:

    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
    
  • Gå ner till JDBC-nivån och kör din upsert allt på en gång (idé via det här svaret ):

    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()
    }
    


  1. Postgres rekursiv fråga med row_to_json

  2. mysql_query returnerar endast strängtyp för int/fload db-typ

  3. SQL Unik begränsning över flera tabeller

  4. to_date-funktion med sysdate