Langsame Abfragen bei vielen Datensätzen – Wie Indexe und clevere Abfragen Geschwindigkeit zurückbringen

Access kann schnell – wenn Du ihm hilfst

Viele glauben, Access ist bei großen Datenmengen per se lahm.
Stimmt nicht.
Aber: Du musst nachhelfen.
Die meisten Performance-Probleme liegen nicht in der Menge, sondern in der Struktur.

Ich zeig Dir, was ich bei Kundenprojekten mache, wenn 200.000 Datensätze plötzlich kriechen.

Indexe – das A und O bei großen Tabellen

Grundregel:

  • Wo gefiltert wird → Index
  • Wo sortiert wird → Index
  • Wo gejoint wird → Index

Aber nicht übertreiben.
Zu viele Indexe machen Inserts und Updates langsamer.

Prüfen per VBA:

Sub ZeigeIndexe(tblName As String)
  Dim tdf As TableDef
  Dim idx As Index

  Set tdf = CurrentDb.TableDefs(tblName)

  For Each idx In tdf.Indexes
    Debug.Print idx.Name, "Unique: " & idx.Unique
  Next
End Sub

Indexe setzen per VBA

Sub ErzeugeIndex()
  Dim tdf As TableDef
  Dim idx As Index

  Set tdf = CurrentDb.TableDefs("tblAufträge")
  Set idx = tdf.CreateIndex("idx_KundeID")

  With idx
    .Fields.Append .CreateField("KundeID")
    .Unique = False
  End With

  tdf.Indexes.Append idx
End Sub

SELECT * ist Gift

Wenn Du alle Spalten holst, lädt Access alles – auch die, die Du nicht brauchst.

Besser:

SELECT KundeID, Auftragsdatum, Betrag
FROM tblAufträge
WHERE Status = 'offen';

Je weniger Felder, desto schneller die Übertragung.
Auch übers Netzwerk.

WHERE-Klauseln optimieren

Setze zuerst die selektivsten Bedingungen.
Und keine Funktionen auf Felder, die indiziert sind.

Schlecht:

WHERE YEAR(Auftragsdatum) = 2023

Besser:

WHERE Auftragsdatum BETWEEN #01.01.2023# AND #31.12.2023#

Funktionen auf Spalten → Index wird ignoriert.

Like mit Wildcard vorne? Vergiss es

WHERE Kundenname LIKE "*müller"

→ Kann nicht indexbasiert laufen.
Wenn möglich: nur rechtsseitige Wildcard verwenden.

WHERE Kundenname LIKE "müller*"

Oder bei festen Suchfeldern auf Normalisierung umsteigen.

JOINs vermeiden, wenn’s nicht sein muss

Ich mache lieber zwei einzelne Abfragen, wenn das JOIN-Ergebnis zu groß wird.
Erst relevante IDs filtern, dann Detaildaten holen.

Zwei Schritte statt Monsterabfrage

Dim sqlIDs As String
sqlIDs = "SELECT AuftragID FROM tblAufträge WHERE Status='offen'"

Dim rs As DAO.Recordset
Set rs = CurrentDb.OpenRecordset(sqlIDs, dbOpenSnapshot)

' Dann IDs durchgehen und Details holen
Do While Not rs.EOF
  ' Folgeabfrage hier
  rs.MoveNext
Loop

Nicht schön, aber bei langsamen Serververbindungen oft schneller.

Zwischenergebnisse materialisieren

Große Abfragen in mehrere Schritte aufteilen – mit temporären Tabellen.

CurrentDb.Execute "SELECT KundeID, SUM(Betrag) AS Umsatz INTO tmp_Umsatz FROM tblAufträge GROUP BY KundeID"

Dann in der nächsten Abfrage mit tmp_Umsatz weiterarbeiten.
Access kommt besser klar, wenn es „Pausen“ bekommt.

Abfragen mit Parameter – lieber sauber als dynamisch

Vermeide dynamische SQL-Strings mit Verkettungen.
Nutze Parameterabfragen oder QueryDefs.

Dim qdf As DAO.QueryDef
Set qdf = CurrentDb.CreateQueryDef("", "SELECT * FROM tblKunden WHERE PLZ = [plz]")

qdf.Parameters("plz") = "23552"
Set rs = qdf.OpenRecordset

Das ist sicherer. Und wird von Access besser optimiert.

Backend entlasten – SQL Server statt Jet

Wenn Du regelmäßig > 1 Mio. Zeilen hast: Backend raus.
SQL Server (oder Azure SQL) übernehmen lassen.
Access bleibt Frontend. Geschwindigkeit steigt deutlich.

Performance-Messung einbauen

Ich stoppe gern mit Timer:

Dim t As Single
t = Timer

Call MeineLangsameRoutine

Debug.Print "Dauer: " & Format(Timer - t, "0.000") & " Sekunden"

Oder: Stopwatch-Klasse verwenden. Noch genauer.

Mein Fazit

Langsame Abfragen kommen selten durch zu viele Daten.
Sondern durch fehlende Indexe, schlechte Filter oder unnötige Spalten.
Ich mach’s lieber sauber – dann ist Access auch bei 1 Mio. Zeilen nicht aus der Puste.

Kategorien:

Keine Antworten

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert