Mysql
 sql >> Database >  >> RDS >> Mysql

Copia in blocco un DataTable in MySQL (simile a System.Data.SqlClient.SqlBulkCopy)

Non escludere una possibile soluzione basata su presupposti infondati. Ho appena testato l'inserimento di 100.000 righe da un System.Data.DataTable in una tabella MySQL usando un MySqlDataAdapter#Update() standard all'interno di una Transaction . Ci sono voluti costantemente circa 30 secondi per l'esecuzione:

using (MySqlTransaction tran = conn.BeginTransaction(System.Data.IsolationLevel.Serializable))
{
    using (MySqlCommand cmd = new MySqlCommand())
    {
        cmd.Connection = conn;
        cmd.Transaction = tran;
        cmd.CommandText = "SELECT * FROM testtable";
        using (MySqlDataAdapter da = new MySqlDataAdapter(cmd))
        {
            da.UpdateBatchSize = 1000;
            using (MySqlCommandBuilder cb = new MySqlCommandBuilder(da))
            {
                da.Update(rawData);
                tran.Commit();
            }
        }
    }
}

(Ho provato un paio di valori diversi per UpdateBatchSize ma non sembravano avere un impatto significativo sul tempo trascorso.)

Al contrario, il codice seguente utilizza MySqlBulkLoader ci sono voluti solo 5 o 6 secondi per l'esecuzione ...

string tempCsvFileSpec = @"C:\Users\Gord\Desktop\dump.csv";
using (StreamWriter writer = new StreamWriter(tempCsvFileSpec))
{
    Rfc4180Writer.WriteDataTable(rawData, writer, false);
}
var msbl = new MySqlBulkLoader(conn);
msbl.TableName = "testtable";
msbl.FileName = tempCsvFileSpec;
msbl.FieldTerminator = ",";
msbl.FieldQuotationCharacter = '"';
msbl.Load();
System.IO.File.Delete(tempCsvFileSpec);

... compreso il tempo per scaricare le 100.000 righe da DataTable in un file CSV temporaneo (usando un codice simile a questo ), il caricamento in blocco da quel file e l'eliminazione del file in seguito.