Gibt es eine schnellere Möglichkeit, SqlBulkCopy als eine DataTable zu verwenden?

c# sqlbulkcopy sql-server

Frage

Ich lade eine große Menge von Aufzeichnungen in meine Anwendung (1 Million +) und mache eine Menge Verarbeitung an ihnen. Die Verarbeitung erfordert, dass sie alle im Speicher sind.

Danach möchte ich alle (jetzt modifizierten) Datensätze in eine leere Tabelle ablegen.

Das Laden der Datensätze dauert nur wenige Sekunden, und am Ende habe ich eine große Auswahl an MyRecord Elementen.

Das Speichern mit SqlBulkCopy dauert nur wenige Sekunden.

Allerdings benötigt SqlBulkCopy (glaube ich) eine DataTable - und das Laden meiner Datensätze in eine DataTable ist langsam - etwa 7500 Datensätze pro Minute mit

dataTable.Rows.Add(myRecord.Name, myRecord.Age, ....)

Gibt es einen schnelleren Weg diesen mittleren Schritt durchzuführen?

Akzeptierte Antwort

Die Verzögerung wird verursacht, weil Sie alles in eine DataTable puffern müssen, bevor Sie es an den Server senden. Um eine bessere Leistung zu erzielen, sollten Sie die Datensätze sofort an SqlBulkCopy senden und die Klasse ihre eigene Pufferung und Stapelverarbeitung verwenden lassen.

SqlBulkCopy kann mit einem IDataReader arbeiten. Alle ADO.NET-Datenlesegeräte implementieren diese Schnittstelle, sodass Sie Daten, die Sie von einem beliebigen Datenlesegerät lesen, an SqlBulkCopy übertragen können.

In anderen Fällen können Sie, wenn Sie ein IEnumerable Ihrer Objekte haben, den Objekt-Leser von Marc Gravel aus dem FastMember- Paket verwenden, um einen IDataReader über dem IEnumerable zu erstellen. Dieser Datenleser lädt nicht alles auf einmal, daher werden keine Daten zwischengespeichert, bis SqlBulkCopy danach fragt:

Marc Gravel's Beispiel kopieren:

IEnumerable<SomeType> data = ... 

using(var bcp = new SqlBulkCopy(connection)) 
using(var reader = ObjectReader.Create(data, "Id", "Name", "Description")) 
{ 
  bcp.DestinationTableName = "SomeTable"; 
  bcp.WriteToServer(reader); 
}

Beliebte Antwort

Ich weiß nicht, was das Problem ist. Das Programm läuft unter einer Sekunde. Ich vermute, dass die langsame Geschwindigkeit auf das Lesen von Daten und das Schreiben in DataTable zurückzuführen ist.

       static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("Col A", typeof(int));
            dt.Columns.Add("Col B", typeof(string));
            dt.Columns.Add("Col C", typeof(int));
            dt.Columns.Add("Col D", typeof(string));
            dt.Columns.Add("Col E", typeof(int));
            dt.Columns.Add("Col F", typeof(string));
            dt.Columns.Add("Col G", typeof(int));
            dt.Columns.Add("Col H", typeof(string));
            dt.Columns.Add("Col I", typeof(int));
            dt.Columns.Add("Col J", typeof(string));

            DateTime begin = DateTime.Now;

            for (int i = 0; i < 7500; i++)
            {
                dt.Rows.Add(new object[] {
                    i + 10000, "b", i + 20000, "d", i + 30000, "f", i + 40000, "h", i + 50000, "i"
                });
            }

            DateTime end = DateTime.Now;

            Console.WriteLine((end - begin).ToString());

            Console.ReadLine();
        }


Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow