sql >> データベース >  >> RDS >> Mysql

Anormを使用して、多くの列を持つテーブルでバッチ挿入

    オプションBを使用します。BatchSqlについてはあまり詳しくありません。 前回チェックしてから、クエリのボートロードを順番に実行するだけで、非常に遅いです。すべてを1つのクエリに集約することをお勧めします。少し面倒ですが、1,000個の単一挿入よりも1,000個の挿入で単一のクエリを実行する方がはるかに高速です。

    便宜上、Seqがあるとします。

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

    次に、次のようにクエリを作成できます:

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

    注:

    valuesを確認する必要があります 空でない場合は無効なSQLステートメントが生成されるため、続行する前は空ではありません。

    挿入する行と列の数に応じて、最終的に、プリペアドステートメントを作成したトークンパーサーは、解析するトークンの量(および文字列サイズ)から遅くなります。数列の数百行の後でこれに気づきました。これはある程度軽減できます。強く型付けされた言語であるScalaのおかげで、Int およびLong SQLインジェクションの脅威はありません。これらの列に対してのみ文字列補間/連結を使用してSQLステートメントを準備し、安全でない列をNamedParameterでバインドできます。 通常は。これにより、解析する必要のあるトークンの数が削減されます。



    1. Oracleの文字列から一意の文字を取得するにはどうすればよいですか?

    2. サブクエリと結合

    3. Unixタイムスタンプの変換はMysqlとOracleで異なります

    4. (Python)psycopg2のインストール