2012-04-02 2 views
3

Ich habe eine MSSQL 2008-Tabelle mit ein paar Millionen Datensätze. Ich muss über jede Zeile iterieren, einige der Daten ändern und den aktualisierten Datensatz mithilfe einer C# -Anwendung, die täglich ausgeführt wird, in eine neue Tabelle kopieren.Verarbeiten Sie jede Zeile und kopieren Sie sie in neue Tabelle mit C#

Ich habe versucht, dies mit ADO.NET-Entities zu tun, aber es gibt Speicherprobleme mit dieser Methode beteiligt, nicht zu erwähnen, es ist sehr langsam. Ich habe in Bulk-Copy-Bibliotheken und SQL-nur Möglichkeiten zum Kopieren einer Tabelle in eine andere gelesen, aber keine von ihnen beinhalten Datensätze zu ändern, bevor Sie sie kopieren. Ich muss einen besseren Weg finden, um diese Operation durchzuführen.

+0

Die Dinge Zeile für Zeile zu tun ist normalerweise sehr langsam. Welche Änderungen müssen Sie für jede Zeile vornehmen? Welche RDBMS verwenden Sie auch? SQL Server? Wenn ja, welche Version? – Bridge

+0

Die Datensätze in der Originaltabelle enthalten Rich Text. Ich muss sie alle in einfachen Text konvertieren und die Klartextdatensätze in eine neue Tabelle kopieren. – CalMlynarczyk

+0

@Ked: Ist es geplant, jeden Datensatz in die Anwendung zu laden, zu konvertieren und dann in die neue Tabelle hochzuladen? –

Antwort

3

Da Sie Speicherprobleme erwähnen, schätze ich, dass Sie versuchen, die Millionen Zeilen in den Speicher zu laden, sie zu verarbeiten und dann in die Datenbank zurückzuschreiben. Sie können dies vermeiden, indem Sie die Daten "streamen" anstatt sie vollständig zu laden. Die SqlDataReader wird Pufferung für Sie behandeln, so auf der Leseseite können Sie eine einfache WHILE Schleife, die Zeilen nacheinander abruft. Die eigentliche Konvertierung, die Sie bereits durchgeführt haben, scheint so zu sein, dass Sie nur noch die Ergebnisse in die Datenbank schreiben müssen. IMHO der schnellste Weg, dies zu tun ist, indem Sie einen Puffer von mehreren Ergebnissen (beginnen Sie mit 100, aufarbeiten und sehen, wo der Sweet Spot ist) in einer Datentabelle und dann schieben Sie diese Datentabelle in die Datenbank mit der SqlBulkCopy Klasse. Spülen & wiederholen.

PS: Klingt nach einem "Spaß" -Problem. Haben Sie irgendwo Stichprobendaten, um das zu testen? 5 Stunden klingt wie eine LANGE Zeit für etwas, das zuerst trivial aussieht, dann wieder 20 Millionen mal praktisch nichts summiert sich noch. Genauer gesagt frage ich mich, wie groß die Daten auf der RTF-Seite sind: Sind die Werte im Durchschnitt 2k oder eher 200k? Und auf welcher Hardware läuft das?

+0

Es gibt mehrere Felder in jedem Datensatz, die geschrubbt werden müssen.Kombinieren Sie das mit der ORM-Leistung und geben Sie ihm eine niedrige CPU-Priorität und es dauert sehr lange .. – CalMlynarczyk

+0

@Keedro Und wo genau ist ein ORM in dieser Antwort, die Leistung schadet? Ich habe diesen Ansatz erfolgreich in der Vergangenheit verwendet, obwohl mein Puffer 5000+ war, nicht 100 – Pleun

+0

@Pleun: Ich bezog mich nicht auf seine Antwort, ich reagierte auf seine Frage die Ausführungszeit, die ich sta an anderer Stelle in einem anderen Kommentar. – CalMlynarczyk

3

Die schnellste Möglichkeit wäre, Ihre C# -Anwendungslogik in eine CLR stored procedure umzuschreiben, so dass die gesamte Verarbeitung auf dem Server stattfindet.

+0

Ich denke, eine Funktion ist ein besserer Ansatz. –

+0

Wahr. Obwohl es ein Minenfeld von Anforderungen und Leistung "Gotcha's" für Uneingeweihte ist. – RBarryYoung

+0

FYI, ich reagierte auf @BluesRockAddict und SQLCLR in meinem Kommentar, oben ... – RBarryYoung

1

Bei der Überprüfung im Internet sieht es nach Microsoft's official answer aus, Rich in Text zu konvertieren, um die Daten in ein RichTextBox-Steuerelement zu laden und dann mit der RichTextBox.Text-Eigenschaft herauszuziehen. Das ist eine Menge Gründe, aber vor allem, weil es bedeutet, dass man sich die Hände schmutzig machen muss. Am besten schreiben Sie eine kleine App, die das RichTextBox-Steuerelement aufruft und alle Ihre Daten an die/aus der Datenbank weiterleitet (mit Hilfe der SqlDataReader sollten die von Ihnen erwähnten Speicherprobleme behoben werden).

Nur als eine Frage des Prozesses - ich würde vorschlagen, eine Zwischentabelle zu erstellen, die Ihre "bereinigten" Datenzeilen in vor dem Anhängen an Ihre Produktionstabelle abgelegt werden. Sobald Sie den gespeicherten Proc genau richtig erkannt haben, können Sie einen Trigger erstellen, der den gespeicherten Proc jedes Mal aufruft, wenn ein Datensatz zu Ihrer Dirty-Tabelle hinzugefügt wird. Dies wird letztendlich die Notwendigkeit beseitigen, Ihr Programm jeden Tag auszuführen, um Datensätze zu verschieben, da der Trigger sicherstellen wird, dass es "on the fly" passiert.

Bearbeiten - ein letzter Gedanke

Es fiel mir ein, dass Sie sich nicht wohl Schreiben Stored Procedures und Trigger sein könnte, die in Ordnung ist. Eine "programmatischere" Lösung wäre, alle Dateien in Ihrer Dirty-Tabelle in eine Textdatei mit Trennzeichen zu übertragen, die einfach heruntergeladen und analysiert werden kann. Sobald Sie die Textdatei haben, können Sie sie mit Ihrer App manipulieren (lesen Sie sie, bereinigen Sie sie, erstellen Sie eine bereinigte Datei ... was haben Sie) und laden Sie sie zum Zurücklesen in Ihre Datenbank hoch. Abhängig von Ihrem Komfort/Hintergrund/Fähigkeitsniveau könnte dies die bessere Lösung sein, um die Arbeit zu erledigen.

Hoffe, das hilft!

+0

Ich habe bereits die RichText-to-PlainText-Operation erledigt, aber ich werde auf jeden Fall mit einem Trigger statt über die gesamte Tabelle laufen täglich. – CalMlynarczyk

+0

Sie werden feststellen, dass "Aufrufen des RichTextBox-Steuerelements" von einer SQLCLR-Routine irgendwo zwischen unglaublich schwierig und unmöglich ist und zu dem späteren neigt. – RBarryYoung

+0

@RBarry - vielen Dank, dass Sie das verstanden haben. Aktualisiert. (Ich verwirrt mich beim Lesen MS Clrsp Seite http://msdn.microsoft.com/en-us/library/ms131094.aspx –

1

Verwenden Sie SSIS. Planen Sie einen täglichen Job, der Ihre Transformation durchführt, und führen Sie das SSIS-Paket aus. Dies wird sich um den Batch- und Speicherverbrauch kümmern und Ihnen ein paar fast connectors for the read and write of data anbieten. Sie können Ihren benutzerdefinierten C# -Code (das RTF-Entfernen in reinen Text) als SSIS-Komponente einbetten, siehe Developing Custom Objects for Integration Services.

+0

Dies scheint eine gute Option zu sein, aber ich kann nicht sagen, ob wir SSIS auf unseren Servern verwenden. – CalMlynarczyk

Verwandte Themen