none
Datenbankzugriff sinnvoll steuern RRS feed

  • Frage

  • Hallo Leute,

    ich bin jetzt mit meinem Projekt so ziemlich am Ende. :-)

    Nun habe ich nur noch eine Frage, ob ich die Datenbankzugriffe richtig steuere. Ich habe das Gefühl, dass der DB-Zugriff immer langsamer wird. Vermutlich liegt es an der New-Anweisung (s. nachfolgender Code).

    Ich möchte nach Bestätigung der Enter-Taste im Listview-Control Datensätze für einen bestimmten Mandanten auslesen. Das funktioniert auch. Führe ich die Anweisungen aber mehrmals aus, dann habe ich das Gefühl der Zugriff wird immer langsamer.

    Kann sich einer vielleicht einmal meinen (peinlichen) Code anschauen?

    Das Problem ist die Prozedur 'Read_LuG()'.

        Dim cnLohn As New OleDb.OleDbConnection
        Dim DS As System.Data.DataSet
        Dim DT As System.Data.DataTable
        Dim DR As System.Data.DataRow
        Dim DA As System.Data.OleDb.OleDbDataAdapter
        Dim CB As System.Data.OleDb.OleDbCommandBuilder
        Dim RowIdx As Integer
    
        Dim lngfirstColor As Drawing.Color = Drawing.Color.FromArgb(255, 215, 228, 242)
        Dim lngsecondColor As Drawing.Color = Color.WhiteSmoke
    
    #Region "Datenbank"
    
        Private Sub Read_LuG(ByVal lMandant As Long)
            Dim sql As String
            Dim dLohnmonat As Date
            sql = "SELECT Lohnabrechnungen.*, Lohnabrechnungen.MdNr FROM(Lohnabrechnungen) WHERE (((Lohnabrechnungen.MdNr)=" & lMandant & ")) ORDER BY Lohnabrechnungen.Lohnmonat;"
    
    
            DS = New System.Data.DataSet()                      ' --- Adapter definieren
            DA = New OleDbDataAdapter(sql, cnLohn)              ' --- SQL-DML-Befehle erzeugen
            CB = New OleDbCommandBuilder(DA)                    ' --- Tabelle einlesen
            DA.Fill(DS, "Lohnabrechnungen")                     ' --- Zugriff auf Tabelle
            DT = DS.Tables("Lohnabrechnungen")
    
            Dim r As Long = DT.Rows.Count - 1
            dLohnmonat = DT.Rows(r)("Lohnmonat")
    
            DateTimePicker1.Value = DateAdd(DateInterval.Month, 1, dLohnmonat)
    
        End Sub
    
        Private Sub Find_LuG(ByVal dMonat As Date)
            Dim ci As New System.Globalization.CultureInfo("de-DE")
    
            Dim foundRows() As Data.DataRow
            Dim sSelect As String = "Lohnmonat='" & dMonat.ToString("d", ci) & "'"
            'Dim sSelect As String = "Lohnmonat='01.05.2012'"
            foundRows = DT.Select(sSelect)
            Try
                With foundRows(0)
                    txtLuG1.Text = .Item(2).ToString
                    txtLuG2.Text = .Item(3).ToString
                    txtLuG3.Text = .Item(4).ToString
                    txtLuG4.Text = .Item(5).ToString
                    txtLuG5.Text = .Item(6).ToString
                    txtLuG6.Text = .Item(7).ToString
                    txtLuG7.Text = .Item(8).ToString
                End With
            Catch ex As Exception
                Call Clear_Text()
                Exit Sub
            End Try
    
        End Sub
    
    #End Region

    Vielen Dank im voraus.

    Gruß Ahmed

    Freitag, 15. Juni 2012 06:50

Antworten

  • Hallo,

    das Erzeugen von Klasseninstanzen (also New) ist kaum eine Zeitbremse.

    Was Read_LuG angeht:
    Aus dem Code ist nicht ersichtlich, welche der Variablen später noch gebraucht werden.
    Variablen, die nur in der Methode verwendet werden sollte man auch dort deklarieren,
    damit sie so bald wie möglich wieder entsorgt werden.

    Wenn Du die Daten nur liest, brauchst Du keinen CommandBuilder.
    Den OleDbDataAdapter wiederum kannst Du einmalig erzeugen und mit einem Parameter versehen,
    so dass er wieder verwendet werden kann, mehr siehe 'DataAdapter'-Parameter (ADO.NET)

    Deine SQL Anweisung könnte wiederum gekürzt werden, da sie die MdNr zweimal enthält.
    Optimal wäre nur die Spalten abzurufen, die das Programm im weiteren Verlauf auch verwendet,
    also z. B. (etwas phantasiert anhand der sichtbaren Stellen):

    SELECT MdNr, LohnMonat, Lug1, Lug2, Lug3, Lug4, Lug5, Lug6, Lug7
    FROM Lohnabrechnungen
    WHERE MdNr = ?
    ORDER BY MdNr, LohnMonat;
    Zum Find_Lug sei angemerkt:

    Anstatt sich die Spaltennummern zu verwenden, solltest Du besser mit den Spaltennamen arbeiten.
    Denn die Reihenfolge kann sich irgendwann mal ändern und dann fällt die Codestelle auf die Nase.
    (Was die Geschwindigkeit angeht, spielt das eh nicht mehr messbar).

    Zudem solltest Du foundRows auf Length > 0 abfragen, als eine Ausnahme zu risikieren,
    denn das wiederum ist deutlich schneller als ein Try Catch.

    Gruß Elmar

    • Als Antwort markiert Ahmed Martens Freitag, 15. Juni 2012 07:25
    Freitag, 15. Juni 2012 07:16

Alle Antworten

  • Hallo,

    das Erzeugen von Klasseninstanzen (also New) ist kaum eine Zeitbremse.

    Was Read_LuG angeht:
    Aus dem Code ist nicht ersichtlich, welche der Variablen später noch gebraucht werden.
    Variablen, die nur in der Methode verwendet werden sollte man auch dort deklarieren,
    damit sie so bald wie möglich wieder entsorgt werden.

    Wenn Du die Daten nur liest, brauchst Du keinen CommandBuilder.
    Den OleDbDataAdapter wiederum kannst Du einmalig erzeugen und mit einem Parameter versehen,
    so dass er wieder verwendet werden kann, mehr siehe 'DataAdapter'-Parameter (ADO.NET)

    Deine SQL Anweisung könnte wiederum gekürzt werden, da sie die MdNr zweimal enthält.
    Optimal wäre nur die Spalten abzurufen, die das Programm im weiteren Verlauf auch verwendet,
    also z. B. (etwas phantasiert anhand der sichtbaren Stellen):

    SELECT MdNr, LohnMonat, Lug1, Lug2, Lug3, Lug4, Lug5, Lug6, Lug7
    FROM Lohnabrechnungen
    WHERE MdNr = ?
    ORDER BY MdNr, LohnMonat;
    Zum Find_Lug sei angemerkt:

    Anstatt sich die Spaltennummern zu verwenden, solltest Du besser mit den Spaltennamen arbeiten.
    Denn die Reihenfolge kann sich irgendwann mal ändern und dann fällt die Codestelle auf die Nase.
    (Was die Geschwindigkeit angeht, spielt das eh nicht mehr messbar).

    Zudem solltest Du foundRows auf Length > 0 abfragen, als eine Ausnahme zu risikieren,
    denn das wiederum ist deutlich schneller als ein Try Catch.

    Gruß Elmar

    • Als Antwort markiert Ahmed Martens Freitag, 15. Juni 2012 07:25
    Freitag, 15. Juni 2012 07:16
  • Hallo Elmar,

    vielen Dank für Deine Anregungen.

    Ich werde den Code noch einmal überarbeiten.

    Gruß Ahmed

    Freitag, 15. Juni 2012 07:25
  • Hallo Elmar,

    ich habe das jetzt einmal umgestellt und bin der Meinung das es jetzt insgesamt etwas schneller ist. Vor allem die Read_LuG-Funktion ist jetzt auch bei mehrmaligen Gebrauch schneller.

    Vielen Dank.

    Gruß Ahmed

    Freitag, 15. Juni 2012 08:10