SQL Express langsam bei großen Datenmengen?

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von EugenIS.

    SQL Express langsam bei großen Datenmengen?

    Hallo zusammen,

    ich habe in einer Anwendung Probleme mit der Laufzeit einer SQL Express-Datenbank und würde gerne wissen, was ich da falsch mache.

    Ich öffne ca. 15 Tabellen mit jeweils 500.000 und bis zu 1.500.000 Datensätzen. Auf dem Entwicklungs-PC dauert das eine Minute, beim Kunden über 10 Minuten.

    Alles, was mit der Datenbank zusammenhängt, habe ich in einer Klasse untergebracht:

    VB.NET-Quellcode

    1. Public Class clsDB
    2. Public strPcCONN As String
    3. Public sqlCONN As SqlConnection
    4. Public Shared cmb As New SqlCommandBuilder
    5. Public cmArtikel As New SqlCommand
    6. Public daArtikel As New SqlDataAdapter
    7. Public dsArtikel As New DataSet
    8. Public dtArtikel As New DataTable
    9. Public drArtikel As DataRow
    10. Public Function DB_OPEN() As Boolean
    11. Try
    12. strPcCONN = "Server=.\SQLExpress;AttachDbFilename=C:\Users\Public\TESTDB.mdf;Database=TESTDB;Trusted_Connection=Yes;"
    13. sqlCONN = New SqlConnection(strPcCONN)
    14. sqlCONN.Open()
    15. Return True
    16. Catch ex As Exception
    17. strPcMESS = "Error OPEN_DB: " & ex.Message & Chr(10) & "Reason: " & Strings.Right(ex.StackTrace, 50)
    18. MessageBox.Show(strPcMESS, "TESTDB Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
    19. DB_OPEN = False
    20. End Try
    21. End Function
    22. Public Function tArtikel_Update() As Boolean
    23. Try
    24. cmb = New SqlCommandBuilder(daArtikel)
    25. daArtikel.Update(dtArtikel)
    26. tArtikel_Update = True
    27. Catch ex As Exception
    28. strPcMESS = "Fehler tArtikel_UPDATE: " & ex.Message & Chr(10) & "Grund: " & Strings.Right(ex.StackTrace, 50)
    29. MessageBox.Show(strPcMESS, Programmfehler", MessageBoxButtons.OK, MessageBoxIcon.Error)
    30. tZUWE_Update = False
    31. End Try
    32. End Function
    33. End Class


    Der Ablauf sieht dann so aus:

    VB.NET-Quellcode

    1. Public cDB As New clsDB
    2. With cDB
    3. if .DB_OPEN Then
    4. strPcSQL = "SELECT * FROM tblArtikel"
    5. .daArtikel = New SqlClient.SqlDataAdapter(strPcSQL, .sqlCONN)
    6. .daArtikel.Fill(.dsArtikel, strPcSQL)
    7. .dtArtikel = .dsArtikel.Tables(strPcSQL)
    8. .dtArtikel.PrimaryKey = New DataColumn() { .dtArtikel.Columns("ARTNR")}
    9. For Each .drArtikel In .dtArtikel.Rows
    10. ' Datensätze werden verändert
    11. Next
    12. .tArtikel_Update()
    13. .daArtikel.Dispose()
    14. .dtArtikel.Clear()
    15. end if
    16. End With


    Alles ist stark verkürzt dargestellt. Das Hauptproblem ist aber das sehr langsame Öffnen und auch der Update, der ebenfalls extrem lange dauert.

    Ist mein Konzept falsch? Bin für jeden Tipp dankbar!

    Gruß, Schorsch
    nicht so dolle ist, 1.500.00 Datensätze in eie DataTable zu laden - bist du sicher, wirklich alle zu brauchen?

    Updating ist tatsächlich eine langsame Operation. Da kann man was beschleunigen, wenn man sie alle einer TransAction unterordnet.

    Den Zeitunterschied zw. Kunde und dir - kann das auch hardware-begründet sein - also dass dein System vlt. tatsächlich für diese Anforderung günstiger ausgelegt ist?
    Ich würde dir empfehlen es zum einem in den Hintergrund auszulagern und zum anderen vielleicht Entity benutzen. Dort kannst du etwas gezielter vorgehen und vielleicht mit SaveChages() zu arbeiten. Das geht mit Entity in der Tat etwas schneller bei größeren Datensätzen.
    Hallo EugenIS,

    danke für Dein Angebot - sehr freundlich! Ich glaube aber, dass ich Deinen Ansatz verstanden habe, das sollte ich wohl hinbekommen.

    Ich würde also einen SQL-Befehl erstellen und diesen mit ExecuteNonQuery() ausführen. Und dann noch mit Transaktionen arbeiten. Bin gespannt und werde berichten.

    Mit dem Entity-Framework habe ich mich noch nicht beschäftigt, da muss ich mich erst einlesen.

    Danke erstmal, Gruß, Schorsch
    Also wenn du dich noch nie damit beschäftigt hast, dann würde ich an deiner stelle so vorgehen:

    1) Ein Model von deiner Datenbank erstellen, so dass du eine Verbindung hast. Das kannst du dir zusammenklicken (Hinzufügen->Data->ADO.NET Entity Data Model) und alles einfach einfügen.
    2) using (var tmpCon = new deinEntities())....
    3) var deineTabelleOderVariable = tmpCon.Database.SqlQuery<DeineKlasseDieAlsRückgabewertZuErwartenIst>("SELECT blabla FROM blablabla WHERE XX = {0}", IrgendWas).FirstOrDef oder ToList()

    Dabei muss du beachten, dass die Hochkommas ausgelassen werden auch beim String. Das macht er schon von alleine.

    Es gibt sicherlich auch andere Möglichkeiten und wenn du hier paar Experten fragen würdest, wäre es eine Diskussion für das ganze Jahr. Aber so kommst du zumindest wie gewohnt schon mal weiter, ohne deine ganze Software auf irgend was umstellen zu müssen.

    Viel Erfolg.