DataAdapter.Update() große Datenmengen

  • VB.NET

Es gibt 15 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    DataAdapter.Update() große Datenmengen

    Moinmoin,

    für eine Import Routine aus CSV zu Datenbank (MSSQL, MySQL, Accdb, Mdb) benötigt mein Programm bei einer Singlecore Auslastung von 100% gut 20 Minuten.

    Zum Code (Import zu Accdb) …

    VB.NET-Quellcode

    1. Dim DT_Data As New Datatable("tbl_Adressen")
    2. Dim SQLAdapter As New OleDbDataAdapter(Nothing, Conn.Connection)
    3. Dim CommandBuilder As OleDbCommandBuilder = Nothing
    4. With SQLAdapter
    5. For Each Data As DataTable In Me.Data.Tables
    6. CommandBuilder = New OleDbCommandBuilder(SQLAdapter)
    7. .SelectCommand = New OleDbCommand("SELECT * FROM " & Data.TableName, New OleDbConnection(CD.ConnectString))
    8. .MissingSchemaAction = MissingSchemaAction.Add
    9. .Update(Data)
    10. Next
    11. .Dispose()
    12. End With
    13. CommandBuilder.Dispose()
    14. With Conn
    15. If .ConnectionState = ConnectionState.Open Then .Connection.Close()
    16. End With


    Die Me.Data.Tables enthält derzeit 6 Tabellen, je zwei davon haben 2 und 12 Spalten. Das gesamte DataSet belegt im Ram etwa 150 mb.

    Die Schleife durch die 6 Tabellen benötigt bis zu 20 Minuten.
    In der Vergangenheit habe ich schon mehrmals bemerkt, dass der DataAdapter.Update() bei großen Datenmengen sehr lange braucht.
    Lässt sich dies beschleunigen, wie macht ihr das?

    Freundliche Grüße :)
    Wenn es um acces geht, versuche es mit einer schema.ini File. Ich importiere zwar nur ca. 50 MB Datenmenge in 7 csv Dateien (68, 17, 8, 8, 6, 21, 37 Datenfelder), aber das ganze läuft ca. 3 Sekunden. Code kann ich jetzt nicht schicken, aber suche mal im Internet.
    üblicherweise ists nicht die Datenbank, die Ladevorgänge so lahm ausführt, sondern es sind angebundene Datagridviews, die sich mittels Databinding noch während des Ladevorgangs ständig aktualisieren.

    Ansonsten findich dein Post widersprüchlich - was hat CSV damit zu tun?

    BlueLagoonX schrieb:

    für eine Import Routine aus CSV zu Datenbank


    ?
    Ich denke auch nicht, dass die Datenbank der Flaschenhals ist, da es bei MSSQL, MySQL und Accdb/MdB als Ziel nahezu gleich schnell ist.

    CSV in sofern, dass ich die meine DateTable welche die Daten aus der CSV nach deim Einlesen durch mein Programm enthält, über SQLAdapter.Update(Data) in die Datenbank geschreiben wird.

    Dabei spielt es eigentlich keine Rolle, woher die Daten für den zu Updatenden DataAdapter kommen. Derzeit sind es ähnliche Daten, die ich als Xml bekomme. Diese muss ich deserialisieren und anschließend in eine Datenbank schreiben.

    Der Flaschenhals ist das SQLAdapter.Update(Data)
    Stellt der Import eine aktualisierung von in der Datenbank bestehenden Datensätzen dar, oder handelt es sich im eine „Neuanlage“? Schildere doch mal den Ablauf eines Imports von Daten aus CSV in eine Datenbank.
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    Hallo

    Sorry das ich mich hier einmische, ich kenne mich mit diesem DataAdapter zeugs nicht aus (zu lange her), denke aber zu wissen wie das Ding arbeitet.

    Das problem wird sein (so denke ich) das hier für jedes Update ein SQL Befehl geschickt wird. Wobei dies vermutlich auch für neue Datensätze gilt.
    Will ich aber mehrere Datensätze aktualisieren und/oder anlegen sollte man Batching verwenden. Das geht viel schneller.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Es handelt sich dabei alles um neue Datensätze. Dies dürfte auch der Grund dafür sein, das der Import (eigentlich Update) es so lange dauert.

    Ich dachte auch schon an das Erstellen einzelner SQL Strings, welche als Insert die Daten in die Datenbank schreiben. Ob dies allerdings schneller ist, wage ich zu bezweifeln. Was meint ihr?

    BlueLagoonX schrieb:

    Ich dachte auch schon an das Erstellen einzelner SQL Strings

    Na eben nicht einzeln, sondern in Portionen. Man kann per Batching die Commands zusammenfassen. Also nicht für jeden neuen eintrag einen Befehl absetzen sondern immer 10 oder 20 oder 50 Inserts zusammenfassen.
    Das geht schon mal um einiges schneller.

    Grüße
    sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Würde die Daten auch direkt in die DB schreiben. Finde den Vorschlag von @Nofear23m gut
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    "Batching" kenne ich nicht. Aber ich hab mich mal über "Bulk-Insert" informiert.
    Keine praktische Erfahrung, aber nach den Informationen wird das wohl grauenhaft schnell sein:
    Man erstellt eine DataTable mit allen Datensätzen, und übergibt sie dem Aufruf einer geeigneten StoredProcedure. (Sql-Server)

    ErfinderDesRades schrieb:

    "Batching" kenne ich nicht. Aber ich hab mich mal über "Bulk-Insert" informiert.


    ​Schnell is der Bulk-insert schon, aber höchst unsicher. Man schaltet eigentlich jegliche Sicherheitsmechanismen des Servers aus, kloppt den Kram da rein und dann schaltet man sie wieder an. Auf doppelte IDs oder ähnliches wird dann garnicht mehr geprüft. Ich würde da die Finger von lassen.
    ach - geht BulkInsert also auch ohne StoredProcedure?

    Weil wenn mit SP kannste da ja jede erdenkliche Sicherheitsvorkehrung implementieren.

    Doppelte Ids täte ich denken, können nicht auftreten, wenn man PrimKeys mit AutoIncrement verwendet (was weitverbreiteter Standard ist)

    Und konkret hier:

    BlueLagoonX schrieb:

    Es handelt sich dabei alles um neue Datensätze.
    scheint mir Bulk-Insert genau das Mittel der Wahl.

    Ansonsten haste vmtl. recht, dass BulkInsert eine Optimierung ist, und wie jede Optimierung weniger flexibel einsetzbar als das jeweilige unoptimierte Standard-Verfahren.
    Aber ebenfalls wie bei jeder Optimierung: Hat man einen Engpass (hier: Insert-Performance) muss man Optimierungen in Betracht ziehen.

    Wie gesagt: Von "Batching" habich noch nie gehört - vlt. ist das ja eine bessere Optimierungs-Alternative als BulkInsert.
    In Bezug auf Umständlichkeit und Sicherheit kann das gut sein, und wenn die Performance dann hinlangt ists ja ok.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()