2015-06-03 5 views
7

Ich migriere mein Programm von Microsoft SQL Server zu MySQL. Alles funktioniert gut, außer einem Problem mit Massenkopieren.Massenkopieren einer DataTable in MySQL (ähnlich wie System.Data.SqlClient.SqlBulkCopy)

In der Lösung mit MS SQL sieht der Code wie folgt aus:

connection.Open(); 
SqlBulkCopy bulkCopy = new SqlBulkCopy(connection); 
bulkCopy.DestinationTableName = "testTable"; 
bulkCopy.WriteToServer(rawData); 

Jetzt versuche ich, etwas ähnliches für MySQL zu tun. Da ich denke, dass es eine schlechte Leistung geben würde, möchte ich das DataTable nicht in eine CSV-Datei schreiben und die Einfügung von dort mit der Klasse MySqlBulkLoader machen.

Jede Hilfe würde sehr geschätzt werden.

+0

möglich Duplikat von [Kann ein C# -Programm eine Textdatei in den Speicher lesen und dieses Objekt dann an eine Methode übergeben, die einen Dateinamen benötigt?] (Http://stackoverflow.com/questions/6308208/can-ac-sharp- program-read-a-text-Datei-in-memory-and-then-pass-dass-object-to) –

+0

Auch eine andere Antwort [hier] (http://stackoverflow.com/a/23537155/2144390). Was die Leistung betrifft, haben Sie Tests durchgeführt, um zu sehen, ob das Auslagern der Daten auf die Festplatte und die Verwendung von 'MySqlBulkLoader' wirklich ein Problem darstellen oder tatsächlich schlimmer sein werden als bei anderen" Rollen Sie Ihre eigenen "Lösungen, die keine temporäre Datei verwenden? –

Antwort

7

Da ich denke, dass es schlechte Leistung wäre, möchte ich nicht die DataTable in eine CSV-Datei schreiben und die Einfügung von dort mit der MySqlBulkLoader-Klasse tun.

Schließen Sie eine mögliche Lösung basierend auf unbegründeten Annahmen nicht aus. Ich habe gerade die Einfügung von 100.000 Zeilen von einer System.Data.DataTable in eine MySQL-Tabelle mit einem Standard MySqlDataAdapter#Update() innerhalb einer Transaction getestet. Es dauerte durchweg etwa 30 Sekunden laufen:

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

(Ich habe versucht, ein paar verschiedene Werte für UpdateBatchSize aber sie scheinen keinen signifikanten Einfluss auf die verstrichene Zeit zu haben.)

von Kontrast: der folgende Code MySqlBulkLoader mit dauerte nur 5 oder 6 Sekunden ...

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

... einschließlich der Zeit ausführen, um die 100.000 Zeilen aus der Datentabelle in eine temporäre CSV-Datei Dump (mit Code ähnlich wie this), Massen-Laden von dieser Datei und Löschen der Datei danach.

+0

Vielen Dank sehr viel. Das habe ich nach dem zweiten Kommentar selbst herausgefunden :-) –

Verwandte Themen