Office: (Office 2016) Geschwindigkeitsprobleme

Helfe beim Thema Geschwindigkeitsprobleme in Microsoft Access Hilfe um das Problem gemeinsam zu lösen; Hallo, ich habe mit Access 2010 und VBA eine Auswertung einer Datenbank erstellt. Mit Access wurden etwa 10 Datensätze pro Sekunde verarbeitet. Mit... Dieses Thema im Forum "Microsoft Access Hilfe" wurde erstellt von JoeEckMosDe, 19. Januar 2020.

  1. Geschwindigkeitsprobleme


    Hallo,

    ich habe mit Access 2010 und VBA eine Auswertung einer Datenbank erstellt.
    Mit Access wurden etwa 10 Datensätze pro Sekunde verarbeitet.
    Mit dem Umstieg auf Access 2016 braucht ein Datensatz etwa 2 Sekunden.
    Warum gibt es diesen Unterschied mit Fakator 20?
    (Zur Optimierung könnte ich die Bildschirmausgabe unterdrücken. Anderseits brauche ich Bildschirmausgaben. In 2010 hatte ich auch keine Bildschirmausgaben unterdrückt.)


    Ich hole mir rund 26.000 Personalstammdaten (aus Halle) und zu einer Person weitere Informationen. Die Verbindung ist die Peronalnummer, die als Parameter übergeben wird.

    Dann wird der Datenbestand aus einem zweiten Standort (aus Magdeburg) abgeholt (mit ebenfalls rund 26.000 Personalstammdaten).
    Beide Personaldaten werden in eine neue Datenbank-Tabelle (LSA) geschrieben.

    Gibt es Anweisungen, die in Access 2016 nicht mehr verwendet werden sollen?

    Option Compare Database
    Option Explicit

    Sub Personal_aus_Hal_bearbeiten() ' + Personal_aus_MD_holen
    Dim db As DAO.Database
    Dim qdf_HAL As DAO.QueryDef
    Dim qdf_Abg As DAO.QueryDef
    Dim qdf_Zug As DAO.QueryDef
    Dim qdf_ATZ As DAO.QueryDef
    Dim rs_HAL As DAO.Recordset
    Dim rs_LSA As DAO.Recordset
    Dim rs_abg As DAO.Recordset
    Dim rs_zug As DAO.Recordset
    Dim rs_atz As DAO.Recordset
    Dim anzahl_Personal
    Dim zaehler
    Dim VergleichsPnr As DAO.Parameter
    Dim VergPnr As DAO.Parameter

    Set db = CurrentDb
    Set qdf_HAL = db.QueryDefs("Halle_Personal")
    Set rs_HAL = qdf_HAL.OpenRecordset
    Set rs_LSA = db.OpenRecordset("Personal_LSA", dbOpenDynaset)
    rs_HAL.MoveLast
    anzahl_Personal = rs_HAL.RecordCount

    zaehler = 0
    rs_HAL.MoveFirst
    Do While Not rs_HAL.EOF And Not rs_HAL.BOF
    rs_LSA.AddNew
    rs_LSA!pnr = rs_HAL!pnr
    rs_LSA!pnr_LSD = rs_HAL!pnr_LSD
    rs_LSA!name = rs_HAL!name
    rs_LSA!vorname = rs_HAL!vorname
    rs_LSA!titel = rs_HAL!titel
    rs_LSA!gebdat = rs_HAL!gebdat
    rs_LSA!geschl = rs_HAL!geschlecht
    rs_LSA!behind = rs_HAL!behind
    rs_LSA!Status = rs_HAL!Status
    rs_LSA!vws = rs_HAL!vws
    rs_LSA!rws = rs_HAL!rws
    rs_LSA!stammschule = rs_HAL!stammschule
    rs_LSA!stammschultyp = rs_HAL!stammschultyp
    rs_LSA!typstammschule = rs_HAL!typstammschule
    rs_LSA!kapitel = rs_HAL!kapitel
    rs_LSA!lkstammschule = rs_HAL!lkstammschule
    rs_LSA!rv = rs_HAL!rv
    rs_LSA!rv_gruppe = rs_HAL!rv_gruppe
    rs_LSA!vg = rs_HAL!vg
    rs_LSA!db = rs_HAL!db
    rs_LSA!adb = rs_HAL!adb
    rs_LSA!amt = rs_HAL!amt
    rs_LSA!Quelle = rs_HAL!Quelle
    rs_LSA!statusdatum = rs_HAL!statdat

    Set qdf_Abg = db.QueryDefs("Halle_Abgänge")
    Set VergleichsPnr = qdf_Abg.Parameters("Vgl_Pnr")
    VergleichsPnr.Value = rs_HAL!pnr
    Set rs_abg = qdf_Abg.OpenRecordset
    If Not rs_abg.EOF Or Not rs_abg.BOF Then
    rs_abg.MoveLast
    rs_LSA!anzahlAbgänge = rs_abg.RecordCount
    rs_abg.MoveFirst
    rs_LSA!abg = rs_abg!abg
    rs_LSA!abgdat = rs_abg!abgdat
    rs_LSA!ABGNr = rs_abg!vorart
    If rs_abg!vorart = "60" Then
    'Altersteilzeit
    rs_LSA!atz_frist_aus50 = rs_abg!atz_frist_50

    Set qdf_ATZ = db.QueryDefs("Halle_Teilzeit")
    Set VergPnr = qdf_ATZ.Parameters("Vgl_Pnr")
    VergPnr.Value = rs_HAL!pnr
    Set rs_atz = qdf_ATZ.OpenRecordset
    If Not rs_atz.EOF Or Not rs_atz.BOF Then
    rs_atz.MoveFirst
    rs_LSA!atz_art = rs_atz!bezeichnung
    rs_LSA!ATZ_Beg_aus30 = rs_atz!Beginn
    rs_LSA!ATZ_Frist_aus30 = rs_atz!frist
    rs_LSA!ATZ_druck_aus30 = rs_atz!druck
    End If

    End If
    End If

    Set qdf_Zug = db.QueryDefs("Halle_Zugänge")
    Set VergleichsPnr = qdf_Zug.Parameters("Vgl_Pnr")
    VergleichsPnr.Value = rs_HAL!pnr
    Set rs_zug = qdf_Zug.OpenRecordset
    If Not rs_zug.EOF Or Not rs_zug.BOF Then
    rs_zug.MoveLast
    rs_LSA!anzahlZugänge = rs_zug.RecordCount
    rs_zug.MoveFirst
    rs_LSA!Zugangsgrund = rs_zug!ZugGrund
    rs_LSA!letzterZugang = rs_zug!Beginn
    End If

    Set qdf_Zug = db.QueryDefs("Halle_Zugänge_befristet")
    Set VergleichsPnr = qdf_Zug.Parameters("Vgl_Pnr")
    VergleichsPnr.Value = rs_HAL!pnr
    Set rs_zug = qdf_Zug.OpenRecordset
    If Not rs_zug.EOF Or Not rs_zug.BOF Then
    rs_zug.MoveLast
    rs_LSA!AnzahlBefristete = rs_zug.RecordCount
    rs_zug.MoveFirst
    'rs_LSA!Zugangsgrund = rs_zug!ZugGrund
    rs_LSA!letzteBefristung_Beginn = rs_zug!Beginn
    rs_LSA!letzteBefristung_Ende = rs_zug!frist
    rs_LSA!letzteBefristung_Grund = rs_zug!ZugGrund
    End If

    Set qdf_Zug = db.QueryDefs("Halle_Überführung_EP13")
    Set VergleichsPnr = qdf_Zug.Parameters("Vgl_Pnr")
    VergleichsPnr.Value = rs_HAL!pnr
    Set rs_zug = qdf_Zug.OpenRecordset
    If Not rs_zug.EOF Or Not rs_zug.BOF Then
    rs_zug.MoveFirst
    rs_LSA!UeberführungEp13 = rs_zug!UeberfuehrungEpl13
    End If

    zaehler = zaehler + 1
    If zaehler Mod 20 = 0 Then
    StatusBar ("Datensatz " & zaehler & " von " & anzahl_Personal & " aus Halle")
    End If
    rs_LSA.Update
    rs_HAL.MoveNext
    Loop

    Set VergleichsPnr = Nothing
    Set VergPnr = Nothing
    Set rs_abg = Nothing
    Set rs_zug = Nothing
    Set rs_HAL = Nothing
    Set rs_atz = Nothing
    Set qdf_Abg = Nothing
    Set qdf_Zug = Nothing
    Set qdf_ATZ = Nothing
    Set db = Nothing

    End Sub

    :)
     
    JoeEckMosDe, 19. Januar 2020
    #1
  2. Deine Frage kann ich nicht beantworten.
    Allerdings arbeitest Du hier mit einem Hochmaß an Umständlichkeit. Bei Verwendung von richtigen Abfragen könntest Du eine Stunde eher Feierabend machen.
     
  3. Das mag sein, dass man den Quellcode optimieren könnte oder die Datenbankabfragen geschickter wählen kann.
    Das ist doch nicht der Kern meiner Anfrage.

    Die Procedure wurde eh angestoßen und hat dann allein gearbeitet.
    Warum braucht der selbe Code mit Access 2016 rund 20 mal mehr Zeit als mit Access 2010. Der PC ist der selbe, Windows 10 bleibt gleich. Es muss an Access liegen.

    Ein ähnliches Problem habe ich bei VBA-Programmierungen in Excel.
    Die Prozedur in Excel 2010 war nach einer Sekunde fertig.
    Mit Excel 2016 dauert es 15 Sekunden.
    Auch da wurde die Laufzeit deutlich vergrößert.
     
    JoeEckMosDe, 20. Januar 2020
    #3
  4. Geschwindigkeitsprobleme

    Ich sprach nicht davon, dass man die Pferde vor seiner Postkutsche etwas mehr oder weniger antreibt. Ich meinte eher, dass man einen ICE oder ein Flugzeug benutzt für seinem Weg von München nach Hamburg.
    Für ein Grundverständnis, VOR allem Code: Grundlagen - SQL ist leicht (0) - Vorspiel

    Darauf hatte ich selber auch schon hingewiesen, es ist mir also bewusst.
    Aber der Umgang mit Pferden ist mir mangels Praxis nicht mehr so vertraut.

    Wenn ich aber ungeachtet von mangelnder Kenntnis raten sollte, würde ich nennen:

    - Solche Programme werden funktionsreicher. Zur Anlagerung von zusätzlicher Funktionalität wird es desweilen günstiger sein, vorhandene Optimierungen einzuschränken.

    - Programme werden nutzerfreundlicher, man könnte auch sagen, in einem höheren Maße idiotensicher. Zur Unterstützung der "Idioten" laufen automatisch mehr interne Prüfungen, Fehlerkorrekturen usw. - ob man es nun braucht oder nicht.

    - Wenn ich das Laden einer Website in einem Browser betrachte: Da wird nicht nur mit dem Inhalteanbieter kommuniziert, sondern mittlerweile mit 5 bis 150 weiteren Stellen irgendwo in der weiten Welt, Tendenz steigend. Warum soll das bei Anwenderprogrammen grundlegend anders sein?

    - Die Bedienung höherer Auflösungen bei zunehmender Grafiklastigkeit wird auch ihren Preis haben.
     
  5. Glaub kaum, dass es an Access liegt.
    Dafür ist der Unterschied zu groß.
     
    Zuletzt von einem Moderator bearbeitet: 7. Januar 2021
    markusxy, 21. Januar 2020
    #5
  6. Hallo,

    Eberhards Kernaussage ist, dass das feldweise Umschreiben aus einem Recordset wie in Deinem Code ein totaler Performancekiller ist und simple Anfügeabfragen eine Bruchteil der Zeit benötigen würden.

    Unabhängig davon habe ich die Erfahrung, dass Office 2016 deutlich langsamer als Office 2010 ist, auch schon gemacht. Recordsets brauchen länger, um geöffnet zu werden. Ein Access-Programm, das für die Generierung von ca. 140 Exceldateien früher 2 Stunden brauchte, benötigt heute bei gleicher Datenmenge mehr als 4 Stunden. Es trat unregelmäßig die Fehlermeldung "die Methode CopyFromRecordSet für das Objekt Range ist fehlgeschlagen" auf - die wird nun über eine Schleife (bei nicht aktualisiertem Recordset) immer wieder aufgerufen und funktioniert dann bei 2., 3. oder nten Aufruf. Zum Teil sind in den Recordsets nur 2 kleine Datensätze, und die stammen auch noch aus eine lokalen, verknüpften Tabelle.

    Dein Code wird auch für Dich besser lesbar, wenn Du ihn a)vernünftig einrückst und b) hier im Forum den Code in Codetags setzt.

    Gruß
    Fred
     
    Fred_BS, 22. Januar 2020
    #6
  7. Danke für Deine Erklärung.
    Mein Quellcode ist eigentlich eingerückt. Sonst würde ich den Überblick verlieren.
    Duch mehrfaches Kopieren ist dieses aber irgendwie verloren gegangen.
    Ja das mit den Code-Tags habe ich vergessen-sorry.

    Diesen Code habe ich vor vielen Jahren geschrieben. Damals dachte ich, es besonders gut zu machen, weil ich sehr systematisch vorgegangen bin. Jetzt würde ich es auch anders bewerkstelligen.
    Ich habe auch in diesem Projekt (nicht in der Procedur) viele andere Dinge, die später abgefragt wurden, die ich dann mit Anfügeabfragen realisiert habe.

    Das Projekt und damit diese Procedure wird jeden Monat einmal ausgeführt. In rund einen Jahr soll die Auswertung mit einem neuen viel größerem Produkt ausgeführt werden. (Eierlegende Wollmilchsau)
    Das heißt noch 12 Läufe. Ich will nicht alles umstellen.

    Bisher lief das gesamte Projet rund 2 h. Jetzt einen Tag.
    Ich habe gehofft auf eine Aussage wie:
    nimm nicht das Objekt sondern verwende dieses.
    Aber so ist es auch gut.

    Wir hatten auf den Rechnern erst Office 10. Dann hat die IT dies durch Office 16 ausgetauscht. Könnte es sein, dass dies nicht sinnvoll ist?
    Sollte die IT die Rechner komplett platt machen, damit keine alten Einträge in der Registerdatenbank stehen?

    *Smilie Ich konnte jetzt mehrere Tage nicht aktiv sein, da ich im Fasching aktiv war.*Smilie
     
    JoeEckMosDe, 25. Januar 2020
    #7
  8. Geschwindigkeitsprobleme

    Jetzt bleibt verborgen, welche Objekte in Deinen Augen veränderungswürdig sind und welche unantastbar.

    Mein Tipp (in Wiederholung) wäre:
    => 1) Indexnutzung. Diese kann bei den VBA-Aktionen natürlich nicht eine Rolle spielen. Was wie in den genannten, aber inhaltlich unbekannten Abfragen passiert, kann selbstredend auch niemand erraten.
    => 2) Richtige Abfragen. Bagger statt Sandschaufel, Massendatenverarbeitung statt serielle Einzeldatenverarbeitung.

    Das hieße im Ergebnis, (eigentlich) sämtliche Recordsets streichen.

    Auch gut. Nur nichts verändern.

    Macht bei genannten 52.000 Datensätzen, zu schreiben in eine Tabelle, anderthalb Stunden. Für mich wäre das auch schon undiskutabel.
    Man kennt natürlich nicht die Verbindungsqualität zu den Tabellen, aber alles über 5 Minuten wäre eine herbe Enttäuschung, also für eine Tasse Kaffee oder eine Zigarette darf es nicht reichen.
     
  9. Die einzig pauschale Aussage in dieser Richtung, die mir zu deinem Code einfällt ist: Wenn man ein Recordset öffnet, sollte man es nach Verwendung auch wieder schließen. - Du öffnest gleich einen ganzen Schwarm davon und schließt, soweit ich sehe, kein einziges.
     
    Zuletzt von einem Moderator bearbeitet: 7. Januar 2021
  10. Richtig, und wenn ich mich nicht verzählt habe, werden mit jedem Schleifendurchlauf 6 Recordsets geöffnet. Dabei nicht ganz unwesentlich: Mit jedem Neurecordset erfolgt eine Abfrageausführung (unbekannter Art). Ein Feuerwerk über Stunden. Es kann gar nicht anders sein als dass da Massen an Daten bewegt werden, was dann seine Zeit braucht.
     
  11. > Ich konnte jetzt mehrere Tage nicht aktiv sein, da ich im Fasching aktiv war.

    In Bayern fällt Fasching dieses Jahr auf den 25.2. *biggrin.gif*
     
    CatboyJones, 27. Januar 2020
    #11
Thema:

Geschwindigkeitsprobleme

  1. Diese Seite verwendet Cookies, um Inhalte zu personalisieren, diese deiner Erfahrung anzupassen und dich nach der Registrierung angemeldet zu halten.
    Auf dieser Website werden Cookies für die Zugriffsanalyse und Anzeigenmessung verwendet.
    Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden