Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Stapeleinfügung mit Tabelle mit vielen Spalten unter Verwendung von Anorm

Ich werde mich für Option B entscheiden. Ich bin nicht sehr vertraut mit BatchSql Seit ich das letzte Mal überprüft habe, führt es nur eine Bootsladung von Abfragen nacheinander aus, was schrecklich langsam ist. Ich würde empfehlen, alles in einer einzigen Abfrage zusammenzufassen. Es ist etwas mühsamer, aber viel schneller, eine einzelne Abfrage mit tausend Einfügungen auszuführen als mit tausend einzelnen Einfügungen.

Nehmen wir der Einfachheit halber an, Sie haben Seq von

case class Test(val1: Int, val2: Option[Long], val3: Option[String])

Dann könnten Sie Ihre Abfrage so aufbauen:

val values: Seq[Test] = Seq(....)

/* Index your sequence for later, to map to inserts and parameters alike */
val indexedValues = values.zipWithIndex

/* Create the portion of the insert statement with placeholders, each with a unique index */
val rows = indexValues.map{ case (value, i) =>
    s"({val1_${i}}, {val2_${i}}, {val3_${i}})"
}.mkString(",")

/* Create the NamedParameters for each `value` in the sequence, each with their unique index in the token, and flatten them together */
val parameters = indexedValues.flatMap{ case(value, i) =>
    Seq(
        NamedParameter(s"val1_${i}" -> value.val1),
        NamedParameter(s"val2_${i}" -> value.val2),
        NamedParameter(s"val3_${i}" -> value.val3)
    ) 
}

/* Execute the insert statement, applying the aggregated parameters */
SQL("INSERT INTO table1 (col1, col2, col3) VALUES " + rows)
    .on(parameters: _ *)
    .executeInsert()

Hinweise:

Sie müssen diese values überprüfen nicht leer ist, bevor Sie fortfahren, da sonst eine ungültige SQL-Anweisung generiert würde.

Je nachdem, wie viele Zeilen und Spalten Sie einfügen, werden die Token-Parser, die die vorbereitete Anweisung erstellt haben, aufgrund der schieren Menge der zu analysierenden Token (und der Zeichenfolgengröße) schließlich langsamer. Ich habe das nach ein paar hundert Zeilen mit mehreren Spalten bemerkt. Dies kann etwas abgemildert werden. Da Scala eine stark typisierte Sprache ist, ist Int und Long keine Gefahr für die SQL-Injection darstellen. Sie könnten Ihre SQL-Anweisungen mithilfe von Zeichenfolgeninterpolation/-verkettung nur für diese Spalten vorbereiten und die unsicheren Spalten mit NamedParameter binden normalerweise. Das würde die Anzahl der zu parsenden Token verringern.