SQLite Insert in Datenbank mit über 16000 Datensätzen

  • VB.NET

Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von simpelSoft.

    SQLite Insert in Datenbank mit über 16000 Datensätzen

    Hallo,

    ich habe folgendes Problem:
    Ich habe insgesamt 16 Datatables, die ich per SQL-Abfrage mit Daten fülle.
    Insgesamt komme ich auf ca. 16000 Datensätze, die die 16 Datatables umfassen.

    Nun durchlaufe ich jedes Datatable einzelnd mit einer For each-Schleife.
    Hier ein Beispiel:

    VB.NET-Quellcode

    1. 'Alle Daten auf dem Server durchlaufen:
    2. For Each row As DataRow In taStep.Rows
    3. 'Nachschauen, ob diese id auf der SQLite-Datenbank vorhanden ist:
    4. Dim findRowStep() As DataRow = taStepSQLite.Select("idprocessstepmysql = " & row("idprocessstep"))
    5. If findRowStep.Length > 0 Then
    6. Dim speicherdatumMysql As DateTime = Convert.ToDateTime(row("speicherdatum"))
    7. Dim speicherdatumSQLite As DateTime = findRowStep(0).Item("speicherdatum")
    8. 'Wenn die id vorhanden ist, dann soll nachgeschaut werden,
    9. 'ob sich wirklich was geändert hat -> Sehen wir an beiden Speicherdaten:
    10. If speicherdatumMysql > speicherdatumSQLite Then
    11. 'Dim dicUpdate As New Dictionary(Of String, String)
    12. Dim sqlcmd As New SQLite.SQLiteCommand
    13. Dim sql As String = ""
    14. sql = "UPDATE processstep SET idprocesssub = " & row("idprocesssub") & ", idprocessglobalname = " & row("idprocessglobalname") & _
    15. ", name = '" & row("name") & "', description = '" & row("description") & "', processlevel = " & row("processlevel") & ", " & _
    16. "idprev = " & row("idprev") & ", idnext = '" & row("idnext") & "', del = " & Convert.ToInt32(row("del")) & _
    17. ", position = '" & row("position").ToString().Replace("'", "''") & "', xml_id = '" & row("xml_id") & "'" & _
    18. ", lon = @lon, lat = @lat, idbranch_art = " & row("idbranch_art") & ", idprocessstep_dummy = '" & row("idprocessstep_dummy") & "'" & _
    19. ", manuellgesetzt = " & Convert.ToInt32(row("manuellgesetzt")) & ", x = " & row("x") & ", y = " & row("y") & _
    20. ", idmap = " & row("idmap") & ", speicherdatum = '" & Convert.ToDateTime(row("speicherdatum")).ToString("yyyy-MM-dd HH:mm:ss") & _
    21. "' WHERE idprocessstepmysql = " & findRowStep(0).Item("idprocessstep")
    22. With sqlcmd
    23. .CommandText = sql
    24. .Connection = main.cnSQLite
    25. .Parameters.AddWithValue("@lon", row("lon"))
    26. .Parameters.AddWithValue("@lat", row("lat"))
    27. .ExecuteNonQuery()
    28. End With
    29. End If
    30. Else
    31. 'Wenn die id nicht vorhanden ist, dann soll ein Insert erfolgen.
    32. 'Dabei soll die idprocessstepmysql = der idprocessstep auf dem Server sein.
    33. 'Da sonst die ids durcheinander kommen können.
    34. Dim sqlcmd As New SQLite.SQLiteCommand
    35. Dim sql As String = ""
    36. sql = "INSERT INTO processstep(idprocessstepmysql, idprocesssub, idprocessglobalname, name, description, processlevel " & _
    37. ", idprev, idnext, del, position, xml_id, lon, lat, idbranch_art, idprocessstep_dummy, manuellgesetzt, x, y " & _
    38. ", idmap, speicherdatum) VALUES(" & row("idprocessstep") & ", " & row("idprocesssub") & ", " & row("idprocessglobalname") & _
    39. ", '" & row("name") & "', '" & row("description") & "', " & row("processlevel") & ", " & row("idprev") & _
    40. ", '" & row("idnext") & "', " & Convert.ToInt32(row("del")) & ", '" & row("position").ToString().Replace("'", "''") & "'" & _
    41. ", " & row("xml_id") & ", @lon, @lat, '" & row("idbranch_art") & "', '" & row("idprocessstep_dummy") & "'" & _
    42. ", " & Convert.ToInt32(row("manuellgesetzt")) & ", " & row("x") & ", " & row("y") & ", " & row("idmap") & _
    43. ", '" & Convert.ToDateTime(row("speicherdatum")).ToString("yyyy-MM-dd HH:mm:ss") & "')"
    44. With sqlcmd
    45. .CommandText = sql
    46. .Connection = main.cnSQLite
    47. .Parameters.AddWithValue("@lon", row("lon"))
    48. .Parameters.AddWithValue("@lat", row("lat"))
    49. .ExecuteNonQuery()
    50. End With
    51. End If
    52. Next


    Nun ist das Problem, dass ich alle 16 Datatables wie im obigen Beispiel mit einer For each-Schleife durchlaufe und das dauert ca. 10-15 Minuten.
    Liegt das an der Anzahl der Datensätze, oder liegt das an der Programmierung meinerseits ?
    Wie ihr seht, werden die Daten aus der MySQL-Datenbank gelesen, dann in eine Datatable gefüllt und dann wird mit einer For each-Schleife ein Update oder Insert
    in die SQLite-Datenbank gemacht.

    Ebenfalls ist dies nur beim 1 Klick auf den Button der Fall, da alle Datensätze dann schon in die SQLite-Datenbank importiert wurden.
    Es wird dann nur noch nachgeschaut, ob Änderungen vorgenommen wurden, dies erkennt man anhand des speicherdatums.

    Freue mich über Antworten.

    vivil
    16000 Datensätze sind halt eine Menge zu transportieren, das kenne ich auch so, dass das merklich dauert.
    Was mich sehr wundert ist dein Gemisch aus String-Gefrickel und Verwendung von DB-Parametern.
    Eiglich solltest du 2 Commands aufsetzen können, mit DbParametern im geeigneten Typ, und diese immer wieder verwenden.
    Sonst kannst du Konvertierungs-Probleme kriegen, insbes. mit Datumsen und Fließkommazahlen.

    Aber Geschwindigkeit wird das auch nicht bringen.
    Ihr? immer? o weia!
    String-Gefrickel ist umständlich, fehleranfällig und öffnet Angreifern die Tür für SqlInjection.

    DBParameter sind auf alle Daten anzuwenden, nicht nur für Dezimalstellen.

    Das String-Gefrickel überhaupt möglich ist, ist ein katastrophaler Design-Fehler, der eiglich gesetzlich verboten gehört.

    vivil schrieb:

    Liegt das an der Anzahl der Datensätze, oder liegt das an der Programmierung meinerseits ?


    An der Anzahl der Datensätze liegts nicht.
    Ich schiebe locker 200.000 Rows in 3 Sekunden in die DB (was ich auch beweisen kann).

    Das Zauberwort heißt Bulk-Insert (über BeginTransaction und Commit) und das geht bei SQLite so: LINK.
    Hallo Vivil,
    ich sehe du arbeitest mit sqlite
    ich bin auf der Suche nach Tipps wie ich mit VB.NET 2010 die Sqlite Datenbank zum Laufen bringe.
    Mit den Downloads habe ich immer nur Fehler erhalten.

    ich versuche verzweifelt die System.Data.SQLite in mein Projekt nutzbar zu machen.
    Einbinden bekomme ich hin doch dann diese Fehlermeldung.

    Die DLL "SQLite.Interop.dll": Das angegebene Modul wurde nicht gefunden. (Ausnahme von HRESULT: 0x8007007E) kann nicht geladen werden.

    wie mach ich es richtig
    VB.NET 2010 Express, Win 7, 64 Bit

    kannst Du mir helfen
    mfg H.