MS-Office-Forum

Zurück   MS-Office-Forum > Microsoft Access & Datenbanken > Microsoft Access - Code Archiv
Registrieren Forum Hilfe Alle Foren als gelesen markieren

Banner und Co.

Antworten
Ads
Themen-Optionen Ansicht
Alt 10.08.2018, 20:41   #1
ebs17
MOF Guru
MOF Guru
Standard Grundlagen - SQL ist leicht (11) - Reihenfolge der Abfrageabarbeitung

Zu wissen, was passiert bei so einer Abfrage, ist hilfreich wenn nicht gar notwendig, um funktionierende Anweisungen schreiben zu können, umso mehr, wenn eine Anweisung das machen soll, was man sich selber als Arbeitsablauf vorstellt. Im folgenden Text wird als Abfrage eine Auswahlabfrage verstanden, wobei aber eine Auswahlabfrage unmittelbar auch in Anfügeabfragen, Tabellenerstellungsabfragen und Kreuztabellenabfragen und spätestens als Unterabfrage auch in Aktualisierungsabfragen wiederzufinden ist.

Das Wichtige zuerst: Eine Abfrageanweisung wird nicht von vorne nach hinten oder von oben nach unten ausgeführt, wie man das von prozeduralen Sprachen wie VB(A), Java, Perl, C# u.v.a. kennt und erwartet. Ein zentrales Merkmal von SQL ist, dass nicht gesagt wird, wie etwas gemacht werden soll, sondern dass nur mitgeteilt wird, was zu tun sei. SQL wird deshalb als eine Sprache der vierten Generation klassifiziert. Diese Beschreibung, was zu tun ist, wird letztlich durch den SQL-Optimierer in einen Ausführungsplan überführt, und genau dieser kommt dann nachfolgend zur Anwendung.
Aber zur Orientierung kann man sich folgendes Beispiel anschauen, das schon mal ein paar Einzelheiten enthält:
Code:

SELECT
   X.FeldA, 
   X.FeldB * 1 AS B, 
   COUNT(X.FeldC) AS CC 
FROM 
   TabelleX AS X 
      INNER JOIN TabelleY AS Y 
      ON X.ID = Y.ID 
WHERE 
   X.FeldA = 'xyz' 
GROUP BY 
   X.FeldA, 
   X.FeldB 
HAVING 
   COUNT(X.FeldC) > 3 
ORDER BY 
   X.FeldA
Reihenfolge der Abarbeitung:

1. Schritt: FROM-Teil
Es ist sinnvoll, mit dem FROM-Abschnitt zu beginnen, denn zuerst muss geprüft werden, ob die aufgeführten Tabellen und deren Felder zum Zeitpunkt der Abfrageausführung zugreifbar sind. Eine umbenannte Tabelle, ein verschobenes Backend oder eine Netzwerkunterbrechung wären hinreichende Gründe für einen Abbruch der Verarbeitung.
Nunmehr können Daten geladen werden.

2. Schritt: FROM- und WHERE-Teil
Verknüpfungen in JOIN's und Verknüpfungen und Filterungen im WHERE-Bereich sind erst einmal gleichrangig.
Code:

SELECT A.X, B.Y FROM A INNER JOIN B ON A.ID = B.ID

SELECT A.X, B.Y FROM A, B WHERE A.ID = B.ID
Diese Anweisungen sind in Ausführung und Ergebnis identisch, trotz der unterschiedlichen Formulierung. Das wird für manchen überraschend sein.
Bei mehr als einem Kriterium oder dann auch zusätzlichen Filtern bestimmt der SQL-Optimierer deren Abarbeitungsreihenfolge aus verschiedenen Parametern heraus (Indizierung, Tabellenstatistiken ...). Dessen Arbeitsweise kann man nicht eindeutig vorhersagen. Man kann aber nachträglich im Ablaufplan nachvollziehen, was der SQL-Optimierer ausführt.

3. Schritt: Gruppieren und Aggregation, GROUP BY-Abschnitt
Hier sollte am Rande bekannt sein, dass alle Felder im SELECT-Teil entweder im GROUP BY-Abschnitt enthalten sein müssen oder zu aggregieren sind (Bildung von Summen, Anzahlen, Durchschnitten, Maxima, Minima) oder einfach einen konstanten Inhalt aufweisen. Berechnete Ausdrücke aus solchen Feldern sind auch möglich.

4.Schritt: HAVING-Teil (noch einmal filtern)
WHERE vs. HAVING: WHERE filtert vor der Gruppierung, HAVING nach der Gruppierung. Wenn man sich vor Augen hält, dass Gruppieren eine aufwändige Operation ist (aufwändiger als Filtern), ist es leicht nachvollziehbar, dass man Datenmengen erst verkleinert und dann erst gruppiert (sofern man effizient arbeiten will).
Unter dem Strich würde man HAVING nur auf Aggregate (Summen, Anzahlen, Mittel-, Maximal-, Minimalwerte) anwenden. Alles andere ist "schief".

5. Schritt: Sortieren (ORDER BY) und SELECT-Teil (Berechnungen in Spalten)
Die genaue Abgrenzung der beiden Vorgänge ist schwierig.
Code:

ORDER BY FeldA * FeldC, FeldA, FeldC, FeldB

ORDER BY 4, 1, 3, 2
Die zweite Zeile zeigt eine Alternative, wie man für eine Sortierung statt der Feldnamen oder Berechnungsausdrücke die Nummern der Spalten im SELECT-Teil (mit 1 von links beginnend) einsetzen kann. Das kürzt die Länge der SQL-Anweisung, senkt aber auch etwas die Codelesbarkeit.

6. Schritt: SELECT-Teil (Rename, Neunamensgebung)
Jetzt wird die Ausgabe des Abfrageergebnisses vorbereitet. Im Besonderen werden die angewiesenen Spaltenaliase, die in Folge als Feldnamen nach außen wirken, gesetzt.


Was kann man daraus mal schnell ableiten?

1) Beginnen wir mit dem 6.Schritt, der Neunamensgebung von Spalten. Da diese als allerletzter Schritt erfolgt, dürfte verständlich werden, dass ein solcher Name beim Filtern, Gruppieren und Sortieren noch unbekannt ist und daher bei Verwendung eine Parameterrückfrage oder einen Fehler nach sich zieht. Dort muss also statt des Spaltenaliases der komplette zugehörige Berechnungsausdruck verwendet werden (ohne den Alias).

2) Befindet sich im FROM-Teil eine Unterabfrage oder gespeicherte Abfrage, wird diese zum Laden ausgeführt, also auch vor der aufrufenden Hauptabfrage. Möchte man also sicherstellen, dass bestimmte Filterungen zuerst ausgeführt werden, legt man sie in eine Unterabfrage des FROM-Abschnittes.

3) In Datenbankverarbeitungen hat man es sehr schnell mit sehr großen Datenmengen zu tun. Große Menge => viel benötigte Zeit. Das leuchtet sicher ein. Es gilt aber auch: Eine einfachere Aufgabe ist schneller erledigt als eine aufwändigere Aufgabe. So hat ein Filtern eines Feldes auf einen konstanten Wert (Parameter) ein kleineres Gewicht als Operationen, wo alle Schlüssel der einen Tabelle jeweils mit allen anderen Schlüsseln der gleichen Tabelle (Gruppieren) bzw. mit allen Schlüsseln der zweiten Tabelle (Verknüpfung) verglichen werden müssen.
Da ist es als Stilmittel für eine gute Performance naheliegend, erst zu filtern (wo es schon möglich ist) und so Datenmengen frühestmöglich zu reduzieren, ehe dann die aufwändigeren Operationen folgen. In Umsetzung dessen kommt man dann wieder auf Unterabfragen statt Tabellen.

4) Will man die Logik einer bestehenden Abfrage verstehen, liest man so, wie die Abfrage arbeitet. Man beginnt also mit dem FROM-Abschnitt. Sind dort Unterabfragen enthalten, geht man diese Ebene tiefer und schaut, wo kommen dort die Daten her. Das wird man wiederholen können, bis man auf die Tabellen trifft, die dann wirklich Felder mit Realdaten enthalten. Somit liest man eine Abfrage von innen nach außen. Am Ende merkt man: Ach, das ist ja ganz leicht ...

__________________

Ein freundliches Glück Auf!

Eberhard

Abfrageperformance ist kein Geheimnis
SQL ist leicht: {0}:{1}:{2}:{3}:{4}:{5}:{6}:{7}:{8}:{9}:{10}:{11}
Dein Dankeschön: DBWiki=>Spende
ebs17 ist offline  
verlinken auf Del.icio.us Diese Seite zu Mister Wong hinzufügen
Antworten Auf Beitrag antworten
Ads
Antworten


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Besucher: 1)
 
Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge anzufügen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

vB Code ist An.
Smileys sind An.
[IMG] Code ist An.
HTML-Code ist An.
Gehe zu


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:33 Uhr.


Partner und Co.
Access-Paradies -Alles rund um die Datenbank Microsoft Access -Code -Programme-Tools -Tipps   Kostenlose Tipps & Tricks, Downloads und Programme   www.kulpa-online.com - Tipps - Tricks - Tutorials - Meinungen - Downloads uvm...   vb@rchiv · Willkommen in der Welt der VB Programmierung   Access-Garhammer - Hier finden Sie jede Menge Beispiel-Datenbanken zu Access und mehr ...   mcseboard.de   Die Top Seite für Excel-VBA-Makros uvm.

Powered by: vBulletin Version 3.6.2 (Deutsch)
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.

Copyright ©2000-2018 MS-Office-Forum. Alle Rechte vorbehalten.
Copyright ©Design: Manuela Kulpa ©Rechte: Günter Kramer
Eine Verwendung der Inhalte in anderen Publikationen, auch auszugsweise,
ist ohne ausdrückliche Zustimmung der Autoren nicht gestattet.