Mysql
 sql >> Base de données >  >> RDS >> Mysql

Copier en bloc un DataTable dans MySQL (similaire à System.Data.SqlClient.SqlBulkCopy)

N'excluez pas une solution possible basée sur des hypothèses non fondées. Je viens de tester l'insertion de 100 000 lignes à partir d'un System.Data.DataTable dans une table MySQL en utilisant un MySqlDataAdapter#Update() standard dans une Transaction . L'exécution prenait systématiquement environ 30 secondes :

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

(J'ai essayé quelques valeurs différentes pour UpdateBatchSize mais ils ne semblaient pas avoir d'impact significatif sur le temps écoulé.)

En revanche, le code suivant utilisant MySqlBulkLoader n'a pris que 5 ou 6 secondes pour s'exécuter ...

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

... y compris le temps de vider les 100 000 lignes du DataTable dans un fichier CSV temporaire (en utilisant un code similaire à ceci ), chargement en bloc à partir de ce fichier, puis suppression du fichier par la suite.