SQL DELETE in manchen Situationen zu langsam

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

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von SchorschCode.

    SQL DELETE in manchen Situationen zu langsam

    Liebe Leute,

    ich verwende folgenden Code um Datenzeilen aus einer .mdb Datenbank zu löschen, wenn diese vorhanden sind:

    VB.NET-Quellcode

    1. Dim conn As OleDbConnection = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & Path.Combine(BONitERP2_DatenOrdner, "Auftraege_DB.erp2") & "; Jet OLEDB:Database Password=" & DatenbankPasswort & ";")
    2. Dim cmd As New OleDbCommand
    3. Dim sql As String
    4. cmd.Connection = conn
    5. conn.Open()
    6. sql = "SELECT COUNT(auftragsnummer) FROM auftrag WHERE auftragsnummer='" + TempAuftragsNummer + "'"
    7. cmd = New OleDbCommand(sql, conn)
    8. Dim existiert As Long = CLng(cmd.ExecuteScalar())
    9. If existiert <> 0 Then
    10. sql = "DELETE FROM artikel WHERE auftragsnummer='" + TempAuftragsNummer + "';"
    11. cmd = New OleDbCommand(sql, conn)
    12. cmd.ExecuteNonQuery()
    13. End If


    Das funktioniert soweit ganz gut und zu 99,9% immer auch sehr schnell innerhalb von wenigen Millisekunden.
    Hie und da kommt es jedoch vor, dass der DELETE Befehl 10-30 Sekunden den Task anhält. Besonders dann, wenn die Datenbank schon etwas größer ist und ich darüber übers Netzwerk zugreife (5 GBit LAN). Ich habe aber kein Muster herausfinden können, wonach diese "Denkpausen" auftreten. Bei 100 Zugriffen passt es, beim 101 nicht (so in etwas die Musterverteilung).

    Dazu nun meine Frage. Macht es einen Unterschied ob ich in meinem Code

    VB.NET-Quellcode

    1. sql = "DELETE FROM artikel WHERE auftragsnummer='" + TempAuftragsNummer + "';"


    oder

    VB.NET-Quellcode

    1. sql = "DELETE * FROM artikel WHERE auftragsnummer='" + TempAuftragsNummer + "';"


    verwende? (Unterschied ist der Stern nach DELETE).

    Hat jemand eine Idee, warum diese Verzögerungen hie und da auftreten? Macht die Datenbank da irgend eine Rekonfiguration oder so?

    LG Roland
    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at

    dive26 schrieb:

    Hat jemand eine Idee, warum diese Verzögerungen hie und da auftreten?

    Ja, das kenne ich auch von frher von Access. Hier und da will der "Denkpausen" haben. Kannmich erinnern das da hier und da was war. Hatte meisstens aber mit fehlenden oder falschen indizes zu tun.

    Aber....
    Wozu rufst du vorher mit Count ab ob es Datensätze zu löschen gibt nur um diese dann mit genau den selben Parametern zu löschen.

    Es reicht doch "DELETE FROM artikel WHERE auftragsnummer='" + TempAuftragsNummer + "';"
    Es kann dir doch egal sein wieviele Datensätze es gibt oder nicht?

    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. ##

    Wozu rufst du vorher mit Count ab ob es Datensätze zu löschen gibt nur um diese dann mit genau den selben Parametern zu löschen.


    Habe ich versucht und die Geschwindigkeit nachgemessen. Wenn es keinen Eintrag gibt, dann dauert der DELETE Command viel zu lange. Daher ist das vorherige Abfragen erforderlich, was insgesamt viel schneller geht. der Count Befehl dauert nur wenige ms länger - nicht wirklich merkbar.

    Genauso arbeite ich nicht mit Update, sondern mit Delete + Insert, weil letzteres auch performanter ist.
    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at

    dive26 schrieb:

    Genauso arbeite ich nicht mit Update, sondern mit Delete + Insert, weil letzteres auch performanter ist.

    Aber daran merkt man doch schon das etwas nicht stimmt. Das darf doch nicht schneller sein.

    Man sollte eben dem übel auf den Grund gehen anstatt es immer und immer wieder zu umgehen und sich dann zu wundern.
    Ich weis nicht ob es Performance-Analyse-Tools gibt wie bei MS SQL. Bei nem SQL Server kann ich mir z.b. im Management Studio genau ansehen was warum wie lange dauert.
    vieleicht gibt es sowas auch für Access.

    Aber es hört sich schon irgendwie nach einem Performanceproblem mit der Indexierung an.Poste doch mal die Tabellendefinietion der obigen Tabelle.

    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. ##

    Aber es hört sich schon irgendwie nach einem Performanceproblem mit der Indexierung an.Poste doch mal die Tabellendefinietion der obigen Tabelle.


    Wenn es ein Performanceproblem mit der Indexierung ist, würde es dann nicht jedesmal auftreten? Es tritt nur hie und da auf. Den ganzen Tag gehts auch einwandfrei und superschnell. Dann hast einen einzeigen Auftrag auf den Du bis zu 30 Sekunden wartetst. Und dieser unterscheidet sich auch nicht von anderen - daher die Verwunderung. Würde es an der Gesamt-Datenbankperformance liegen, dann wären ja alle Zugriffe langsam. Aber der Unterschied von 0,5 Sekunden und 30 Sekunden ...

    Ich habe in den Tabellen-Feldern absichtlich keine Indizes gesetzt, da diese die Aktualisierungen mit Insert sehr ausbremsen. Habe mich im letzten Jahr viel mit diesen Datenbanken und die performantesten Arten zur Abfrage/Aktualisierung auseinandergesetzt. Und die meisten Beiträge in diversen Foren rieten von einer Indizierung wegen Performanceeinbußen bei der Aktualisierung der Datensätze ab.

    Meine einzigen Analyse-Tools ist die Praxisanwendung selbst.
    Ich habe im Hintergrund ein Logfile mitlaufen wo ich eine Zeitmessung verschiedenster Datenbankzugriffe vornehme. Da ist leider auch kein Muster erkennbar - außer, dass es beim DELETE Befehl auftritt.

    Aber daran merkt man doch schon das etwas nicht stimmt. Das darf doch nicht schneller sein.


    Werde das "Count" mal testweise rausnehmen und ein paar Tage ohne probieren. Womöglich ist es wirklich unnötig.

    Wegen dem DELETE * FROM oder DELETE FROM - bewirkt der Stern etwas positiv oder negativ? Funktionieren würden beide Varianten.

    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at
    @dive26
    Den Performanceunterschied gibt es aber nicht bei gleichen Auftragsnummern, oder?
    Im Prinzip "sucht" die Datenbank ja nach den zu löschenden Einträgen.
    Da kein Index auf Auftragsnummer liegt und du sehr viele Daten hast, kann das schon mal etwas länger dauern.
    Allerdings ist das Verhalten "oft sehr schnell, selten extrem langsam" trotzdem komisch.

    Ich würde einen Index ausprobieren und schauen, ob die inserts dann noch im zeitlichen Rahmen sind.
    Ich habe nun testweise den Count-Code rausgenommen und auf das Feld "Auftragsnummer" einen Index gesetzt.
    Mal sehen ob das Problem damit gelöst wurde. Zumindest dauern jetzt die Schreibzugriffe mit aktiviertem Index schon ein paar ms messbar länger. Aber damit könnte man leben.
    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at
    Willst du den absichtlich warten bis das Löschen fertig ist? Andernfalls einfach das Löschen Asynchron (ohne await) laufen lassen.

    Z.B.
    Task.Run( AddressOf Loeschen)
    "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 Roland,

    dein Post ist zwar schon etwas älter, meine Erfahrung möchte ich dir aber nicht vorenthalten.

    In solchen Fällen, wie du sie beschrieben hast, baue ich die Db immer komplett neu auf. Das bedeutet:

    - neue DB anlegen
    - Tabellenstrukturen, Indizes und Beziehungen erstellen
    - Tabellen aus der "alten" DB einbinden
    - Tabellen in der "neuen" DB über Abfragen hinzufügen

    Ich habe die Erfahrung gemacht, dass eine Reorganisation nach einem Absturz der DB nicht zwangsläufig zu einer komplett korrekten DB führt.

    Nach dem Neuaufbau ist ein solch eigenartiges Verhalten meistens weg.

    Gruß Schorsch