- Fachgebiet Datenbanken und Informationssysteme

Werbung
Fachgebiet Datenbanksysteme
Institut für Informationssysteme
Fachbereich Informatik
Universität Hannover
Bachelorarbeit
im Studiengang Angewandte Informatik
Erweiterung eines relationalen Anfragesimulators
um eine regelbasierte Steuerung von
physischen Optimierungsregeln
Moritz Diehle
Matr.Nr. 2003050
16. August 2004
Erstprüfer: Prof. Dr. Udo Lipeck
Zweitprüfer: Dr. Hans-Hermann Brüggemann
Betreuer: Dipl.-Math. Mazeyar E. Makoui
Erklärung
Hiermit versichere ich, Moritz Diehle, die vorliegende Bachelorarbeit ohne fremde Hilfe
und nur unter Verwendung der von mir aufgeführten Quellen und Hilfsmittel angefertigt
zu haben.
Hannover, 16. August 2004.
Danksagung
An dieser Stelle möchte ich mich bei allen bedanken, die mich während dieser Arbeit
unterstützt haben. Besonderer Dank geht an Herrn Prof. Dr. Lipeck, der mich durch seine
Fragen auf mögliche Schwachpunkte in Implementierung und Argumentation hinwies.
Desweiteren möchte ich Herrn Dr. Brüggemann für seinen Einsatz als Koreferent danken.
Weiterhin möchte ich meinem Betreuer Dipl.-Math. Mazeyar E. Makoui für seine fortwährende Motivation und Herrn Christoph Echtermeyer für seine konstruktive Kritik
danken.
Außerdem möchte ich noch meinen Eltern danken, die mir dieses Studium ermöglicht
haben.
Hannover, 16. August 2004
Zusammenfassung
Ziel der Arbeit ist die Erweiterung des vorhandenen regelbasierten Anfragesimulators
RELOpt. Schwerpunkt sind hier die regelbasierte Steuerung von physischen Optimierungsstrategien. Außerdem sollen kostenbasierte Aspekte betrachtet und implementiert
werden.
Hauptbestandteil dieser Arbeit ist die über die grafische Benutzerschnittstelle mögliche
Auswahl der neuen Regeln sowie der daraus resultierenden Strategien. Dabei soll die
Bildung von Regelgruppen durch Zusammenfassen von Regeln, sowie deren Iteration
ermöglicht werden.
Ein weiterer Teil dieser Arbeit behandelt die Anbindung von RELOpt an eine OracleDatenbank. Über diese Schnittstelle kann der Nutzer Tabellen und ihre Attribute, sowie
deren Metadaten in Richtung RELOpt importieren. Desweiteren kann man über diese
Schnittstelle die Anfragepläne von RELOpt mit denen der Oracle-Datenbank vergleichen.
Zur Anwendung der obigen Implementierungen sollen Anfragepläne verschiedener Beispielanfragen analysiert, sowie die Oracle-Regelstrategie weitestgehend nachgebildet werden.
Inhaltsverzeichnis
1 Einleitung
1.1 Das System RELOpt . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2 Ziel dieser Arbeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3 Aufbau dieser Arbeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
2
5
6
2 Physische Optimierung
2.1 Physische Optimierungsregeln . . . . . . . . . . . . . . . . . . . . . . . .
7
7
3 Kostenbasierte Optimierung von Verbundfolgen
3.1 Problemstellung . . . . . . . . . . . . . . . . . . .
3.2 Optimierung mit dynamischer Programmierung .
3.2.1 Optimierung von kartesischen Produkten .
3.2.2 Der Algorithmus im Pseudocode . . . . . .
3.2.3 Erweiterung auf Verbunde . . . . . . . . .
3.2.4 Neue Kostenfunktion . . . . . . . . . . . .
3.2.5 Beispiel mit Verbunden . . . . . . . . . . .
3.2.6 Behandlung von Selektionen . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
13
13
14
14
15
17
18
19
19
4 Anbindung an die Oracle-Datenbank
4.1 Importieren von Tabellen . . . . . . . . . . . . .
4.2 Importieren von Statistiken . . . . . . . . . . .
4.3 Import von Anfrageplänen . . . . . . . . . . . .
4.3.1 Der Übersetzer . . . . . . . . . . . . . .
4.3.2 Die Regeln . . . . . . . . . . . . . . . . .
4.4 Anfrageplanerstellung in der Oracle Datenbank
4.5 Implementierung . . . . . . . . . . . . . . . . .
4.5.1 Klassen . . . . . . . . . . . . . . . . . .
4.5.2 Die Regeln . . . . . . . . . . . . . . . . .
4.5.3 Der Übersetzer . . . . . . . . . . . . . .
4.5.4 Die Benutzerschnittstelle . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
21
21
23
24
24
24
26
27
27
29
30
32
5 Experimente und Anwendungen
5.1 Vergleich Join-Order mit Minimum-Selektivity
5.1.1 Beispiele in Form von left-deep-trees“
”
5.1.2 Fazit . . . . . . . . . . . . . . . . . . .
5.2 Operationen der Oracle-Datenbank . . . . . .
5.2.1 Struktur der Oracle-Anfragen . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
33
33
33
34
35
35
vii
.
.
.
.
.
viii
INHALTSVERZEICHNIS
5.3
5.2.2 Umsetzung der Oracle-Operationen in RELOpt
Vergleiche mit der Oracle-Datenbank . . . . . . . . . .
5.3.1 Beispielanfrage ohne Selektion . . . . . . . . . .
5.3.2 Beispielanfrage mit Selektion . . . . . . . . . .
5.3.3 Beispielanfrage mit Kartesischen Produkten . .
5.3.4 Fazit . . . . . . . . . . . . . . . . . . . . . . . .
6 Erweiterungen am Programm RELOpt
6.1 Regeln . . . . . . . . . . . . . . . . . . . . . .
6.2 Regelauswahl . . . . . . . . . . . . . . . . . .
6.3 Zusammenlegung von Relation und Metadaten
6.4 Die Paketstruktur . . . . . . . . . . . . . . . .
6.5 Implementierung . . . . . . . . . . . . . . . .
6.5.1 Vereinheitlichung des Regelsystems . .
6.5.2 Umsetzung der neuen Regelstruktur . .
6.5.3 Anpassung des physischen Optimierers
6.5.4 Die Regelauswahl . . . . . . . . . . . .
6.5.5 Der Join-Order-Algorithmus . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
35
37
37
38
39
42
.
.
.
.
.
.
.
.
.
.
43
43
44
45
46
47
47
48
50
50
51
7 Ausblick
55
Abbildungsverzeichnis
57
Tabellenverzeichnis
59
Literaturverzeichnis
61
Kapitel 1
Einleitung
Datenbankanfragen in SQL sind darauf ausgelegt, Daten aus einer Datenbank zu extrahieren. Da man im allgemeinen nur an den Daten interessiert ist, nicht aber an der Art
und Weise, wie sie gewonnen werden, liegt die optimale Aufbereitung dieser Daten bei
dem verwendeten Datenbanksystem. Der Nutzer legt hier vor allem Wert auf schnelle
Antwortzeiten und die Korrektheit der gelieferten Daten.
In einem Datenbanksystem wird die vom Nutzer gestellte Anfrage zunächst durch einen
Optimierer in einen Anfrageplan umgewandelt. Da sich die Anfragen in den meisten
Fällen durch verschiedene, im Ergebnis äquivalente Anfragepläne ausdrücken lassen, ist
es Aufgabe des Optimierers einen möglichst günstigen Anfrageplan zu finden.
Da der Datenbanknutzer eine schnelle Abarbeitung seiner Anfrage erwartet, kann der
Optimierer im Normalfall nie alle möglichen Anfragepläne erstellen und gegeneinander
abwägen. Bei der Optimierung ist also die Dauer des Vorgangs von entscheidender Bedeutung. Eine Optimierung, die zwar die günstigste Alternative findet, im Endeffekt
aber länger dauert als die erstbeste Variante, ist nicht sinnvoll.
Um günstige Anfragepläne zu ermitteln, ist es im allgemeinen sinnvoll, auf statistische
Daten über den Datenbankinhalt zuzugreifen. Diese können dann von einem kostenbasierten Optimierer verwendet werden, um mittels verschiedener Heuristiken den Anfrageplan zu verbessern.
Die Anfrageoptimierung lässt sich in drei Schritte unterteilen:
1. Algebraische Optimierung
In dieser Phase werden verschiedene algebraische Regeln auf die Anfrage angewendet.
Ziel ist hier die Minimierung der Antwortzeiten, insbesondere bei Verbundoperationen. Dies geschieht zum Beispiel durch Verschieben von Projektionen und die frühe
Anwendung von Selektionen.
1
2
KAPITEL 1. EINLEITUNG
2. Physische Optimierung
In dieser Phase werden die einzelnen Teile der Anfrage durch konkrete physische
Implementierungen der Algorithmen ersetzt. Zum Beispiel könnte hier ein Verbund
durch einen Relationen-Index-Verbund ersetzt werden, wenn ein Index auf die zweite
Relation des Verbundes existiert.
3. Kostenbasierte Optimierung
In dieser Phase werden mittels Kostenfunktionen Anfragepläne erstellt und verglichen,
um den günstigsten zu bestimmen.
Diese Arbeit basiert auf dem in der Diplomarbeit [Mak03] entwickelten und in der Bachelorarbeit [War03] erweiterten Programm RELOpt.
1.1
Das System RELOpt
Bei dem Programm RELOpt handelt es sich um einen Simulator für relationale Anfrageoptimierung. Es wandelt die vom Benutzer eingegebene Anfrage in drei Schritten in
einen Anfrageplan um.
Dazu wird im ersten Schritt ein Baum von algebraischen Operationen erzeugt und mit
Hilfe algebraischer Optimierungsregeln optimiert. Im zweiten Schritt wird der alge”
braische“ Baum in einen Baum aus physischen Operationen transformiert. Eine physische Operation ist die Implementierung einer algebraischen Operation, zum Beispiel der
Nested-Loop-Join, oder eine Index-Selektion mit Duplikateneliminierung. Dies geschieht
mit Hilfe von physischen Transformationsregeln. Im letzten Schritt wird dann der Baum
unter kostenbasierten Gesichtspunkten weiter optimiert.
Der Benutzer kann die Ergebnisse der einzelnen Schritte getrennt voneinander als Text
und als grafische Darstellung betrachten. Die Regeln für die ersten beiden Schritte sind
in Dialogen übersichtlich dargestellt und können vom Benutzer angepasst werden. Die
für die physische und kostenbasierte Optimierung notwendigen Metadaten können vom
Benutzer eingegeben werden. Es folgt ein kurzes Beispiel der drei Schritte.
Relation Kardinalität
Attribute
n(A,R)
P
10
{ID, Name}
ID=10, Name=7
S
20
{MatrNr, Semester}
MatrNr=20, Semester=6
V
30
{VorlNr, gelesenVon} VorlNr=30, gelesenVon=10
H
40
{MatrNr, VorlNr}
MatrNr=20, VorlNr=30
Tabelle 1.1: Beispielrelationen
1.1. DAS SYSTEM RELOPT
3
Relation
Index
P
{ID}
S
{MatrNr}
{VorlNr}
V
H
{MatrNr, VorlNr}
Tabelle 1.2: Indexe der Beispielrelationen
Der Benutzer möchte in der folgenden Anfrage alle Professoren erhalten, deren Vorlesungen von Studenten des fünften Semesters besucht werden. Die benutzten Relationen
sind in Tabelle 1.1 zu finden. Die vorhandenen Indexe der Attribute sind in der Tabelle
1.2 zu finden.
In der Spalte Relation der Tabelle 1.1 findet sich der Name der Relation, die Spalte Kardinalität enthält die Anzahl der Tupel in der Relation. Die Spalte Attribute enthält eine
Liste der Attribute der Relation. Die Spalte n(A,R) enthält die Anzahl der eindeutigen
Tupel pro Attribut. Die Spalte Index der Tabelle 1.2 enthält eine Liste der Attribute,
für die ein Index vorhanden ist.
Die Anfrage in der Notation von RELOpt:
(PROJECTION P.Name
(SELECTION S.Semester=’5’
(JOIN P.ID=V.gelesenVon P
(JOIN V.VorlNr=H.VorlNr V
(JOIN H.MatrNr=S.MatrNr H S)))))
Der Relationale Parser erzeugt daraus den in Abbildung 1.1 gezeigten äquivalenten Baum
aus algebraischen Operationen.1
πP.Name
σS.Semester =’5’
⋊
⋉P.ID =V.gelesenVon
P
⋊
⋉V.VorlNr =H.VorlNr
V
⋊
⋉H.MatrNr =S.MatrNr
H
S
Abbildung 1.1: Anfragebaum der Beispielanfrage
1
für eine Erklärung der Symbole siehe [Lip03], [War03] und [Mak03]
4
KAPITEL 1. EINLEITUNG
Das Ergebnis des Relationalen Parsers wird an den Algebraischen Optimierer übergeben.
Dieser optimiert anhand der ihm gegebenen Regeln den vom Parser erstellten algebraischen Baum. Am Beispiel in Abbildung 1.2 erkennt man, dass die Reihenfolge der Joins
verändert wurde. Außerdem wurde die Selektion nach innen verschoben.
πP.Name
⋊
⋉P.ID =V.gelesenVon
⋊
⋉V.VorlNr =H.VorlNr
V
⋊
⋉H.MatrNr =S.MatrNr
σS.Semester =’5’
P
H
S
Abbildung 1.2: algebraischer Baum der Beispielanfrage
Der physische Optimierer ersetzt nun die algebraischen Operationen anhand von Regeln
durch physische Operationen. In diesem Fall wird zum Beispiel die Projektion durch eine
Relationenscan-Projektion mit Duplikateneliminierung ersetzt. Die Selektion wird durch
eine Relationen-Selektion ersetzt, da es keinen Index für Semester gibt und S auch nicht
nach Semester sortiert ist.
Rel/elim
πP.Name (20)
⋊
⋉Rel-Index
P.ID =V.gelesenVon (8)
⋊
⋉Rel-Index
V.VorlNr =H.VorlNr (11)
⋊
⋉Rel-Index
H.MatrNr =S.MatrNr (10)
Rel
σS.Semester
=’5’ (1)
P
V
H
S
Abbildung 1.3: physischer Baum der Beispielanfrage
Da es für H.MatrNr einen Index gibt, wird der beteiligte Verbund in einen Rel-IndexVerbund2 umgewandelt. Hier existiert ein Index für das Attribut H.VorlNr. Ebenso wird
aus den Verbunden, an denen die Relationen V und P beteiligt sind, jeweils ein RelIndex-Verbund erzeugt. Dies ist möglich, da die für den Verbund benutzten Attribute
über einen Index verfügen. Das Ergebnis der Umwandlung ist in Abbildung 1.3 zu sehen.
2
siehe hierzu [Mak03] oder [War03]
1.2. ZIEL DIESER ARBEIT
5
Am Ende wird der physische Baum an den kostenbasierten Optimierer übergeben. Dieser
verwendet verschiedene Strategien, wie zum Beispiel das Erstellen von Sortierungen oder
Indexen, um mögliche Optimierungen zu finden. Der standardmäßig eingestellte Optimierer kombiniert Sortierungen und Indexe der in den Verbundoperationen vorkommenden Relationen, und ermittelt dann aus den resultierenden Verbunden den Günstigsten.
Index/elim
πP.Name (1)
Tree(P.Name)(12)
⋊
⋉Hash
P.ID =V.gelesenVon (5)
Hash(·)
Hash(·)
⋊
⋉Hash
V.VorlNr =H.VorlNr (5)
P
Hash(·)
Hash(·)
⋊
⋉Hash
H.MatrNr =S.MatrNr (3)
V
Hash(·)
Hash(·)
Rel
σS.Semester
=’5’ (1)
H
S
Abbildung 1.4: Anfragebaum des Beispiels nach der kostenbasierten Optimierung
Die kostenbasierte Optimierung liefert den in Abbildung 1.4 gezeigten Anfragebaum.
Alle Verbunde wurden durch kostengünstige Hash-Verbunde ersetzt. Dies ist möglich,
da für jedes an einem Hash-Verbund teilnehmende Element ein Hash angelegt wird. Die
Projektion wurde durch eine Index-Projektion mit Duplikateneliminierung ersetzt. Dies
wird durch eine vorhergehende Erstellung eines Indexbaumes über die Ergebnisrelation
ermöglicht.
Diese Lösung scheint auf den ersten Blick verwunderlich, da die Erstellung eines Index
eine teure Operation ist. Aufgrund der geringen Anzahl von Tupeln in den Basisrelationen ist diese Lösung aber tatsächlich günstiger. Erhöht man die Anzahl der Tupel in
den Basisrelationen, liefert RELOpt eine Lösung mit einer Sortierung der Ergebnistupel
Sorted/elim
und anschließender Projektion (πP.Name ) mit Duplikateneliminierung.
1.2
Ziel dieser Arbeit
Ziel der Arbeit ist die Erweiterung des Programms RELOpt. Zum einen soll eine flexible regelbasierte Steuerung der algebraischen und physischen Regeln ermöglicht werden.
6
KAPITEL 1. EINLEITUNG
Dies gibt dem Benutzer die Möglichkeit, verschiedene Optimierungsstrategien zu benutzen und zu vergleichen. Weiterhin soll das Programm um einen neuen kostenbasierten
Optimierer erweitert werden. Im einzelnen sind zu entwickeln:
• Erweiterung der algebraischen und physischen Regelsteuerung
RELOpt soll eine flexible regelbasierte Steuerung bekommen, die es dem Benutzer erlaubt, Regelgruppen zu definieren und diese iterativ anzuwenden. Die neue
einheitliche Struktur der Regeln soll späteren Erweiterungen zugute kommen.
• Anbindung an die Oracle-Datenbank
Der Benutzer soll Relationen und ihre Metadaten aus einer Oracle-Datenbank importieren können. Außerdem soll er die Möglichkeit haben, die von RELOpt erzeugten Anfragepläne mit denen des Oracle-Systems zu vergleichen. Zu diesem Zweck
muss RELOpt so erweitert werden, dass es vom Benutzer eingegebene Anfragen in
äquivalente SQL-Anfragen umwandeln kann.
• Implementierung eines neuen kostenbasierten Optimierers
RELOpt soll um einen neuen kostenbasierten Optimierer erweitert werden. Der
Benutzer hat in der grafischen Oberfläche dann die Möglichkeit, zwischen verschiedenen Optimierern zu wählen.
• Anwendungen
Es sollen Vergleiche des neu implementierten Optimierers mit dem vorhandenen
Optimierer durchgeführt werden. Außerdem sollen die von RELOpt gelieferten
Anfragepläne mit denen des Oracle-Systems verglichen werden.
1.3
Aufbau dieser Arbeit
Kapitel 2 behandelt physische Regeln. Im Anschluss daran werden in Kapitel 3 die
Grundlagen und die Implementierung eines neuen kostenbasierten Optimierers behandelt.
Im Kapitel 4 wird die Anbindung an eine Oracle-Datenbank dargestellt. Es finden sich
dort Hinweise zur Benutzung und Erläuterungen zu den Implementierungen.
Kapitel 5 enthält Experimente und Anwendungen des neuen Algorithmus, sowie Vergleiche zur Optimierungsstrategie von Oracle. Kapitel 6 geht auf die Erweiterung des
Programms RELOpt ein. Benutzung der neuen Funktionen und deren Implementierung
sind hier dargelegt.
In Kapitel 7 wird kurz ein Abriss darüber gegeben, welche Aspekte noch weiter betrachtet
werden können. Abschließend findet sich das Literaturverzeichnis, sowie das Tabellenund das Abbildungsverzeichnis.
Kapitel 2
Physische Optimierung
Dieses Kapitel befasst sich mit den im Programm RELOpt implementierten Regeln
und ihrer Umsetzung in ein regelbasiertes System. Durch Analyse der in der Literatur
[Mit95],[Mak03] und [War03] behandelten physischen Optimierungen kann man die im
folgenden Abschnitt beschriebenen Regeln definieren. Diese Regeln können dann später
in einem regelbasierten Optimierer benutzt werden.
2.1
Physische Optimierungsregeln
In diesem Abschnitt benutzte Abkürzungen sind:
R, S
A
M
ϕ
sch(R)
attr(ϕ)
sort(R)
Relationen
ein Attribut
eine Menge
eine Bedingung
Menge der Attribute der Relation R
Menge der in ϕ vorkommende Attribute
einelementige Menge, enthält das sortierte Attribut aus R, falls R
sortiert ist. Ist R nicht sortiert, wird die leere Menge zurückgegeben.
index(R) Menge aller Attribute aus R, die einen Index besitzen
Weiterhin seien folgende Funktionen definiert:
(
#(M ) =
P0
: für M = ∅
1 : sonst
m∈M
attrsch(ϕ, R) =
1 : für #(attr(ϕ) ∩ sch(R)) = 1
0 : sonst
7
8
KAPITEL 2. PHYSISCHE OPTIMIERUNG
1 : für (attr(ϕ) ∩ sort(R)) 6= ∅
0 : sonst
1 : für (attr(ϕ) ∩ index(R)) 6= ∅
0 : sonst
attrsort(ϕ, R) =
attrindex(ϕ, R) =
• [Index|Sorted|Nested]DupProjectionRule
– IndexDupProjectionRule wandelt eine algebraische Projektion in eine physische Index-Projektion mit Duplikateneliminierung um, wenn ein Index auf
das Attribut besteht.
A ∈ index(R)
Index/elim
⇒ πA (R) := πA
(R)
– SortedDupProjectionRule verhält sich ähnlich, nur wird hier auf das Vorhandensein einer Sortierung geprüft.
A ∈ sort(R)
Sort/elim
⇒ πA (R) := πA
(R)
– NestedDupProjectionRule kann auf alle algebraischen Projektionen angewendet werden.
Rel/elim
πA (R) := πA
(R)
• [Merge|IndexIndex|RelIndex|NestedLoop]JoinRule
– MergeJoinRule
Wandelt einen algebraischen Join in einen physischen Merge-Join um, wenn
beide Relationen sortiert vorliegen.
attrsch(ϕ, R) ∧ attrsort(ϕ, R) ∧ attrsch(ϕ, S) ∧ attrsort(ϕ, S)
⇒Ro
nϕ S := R o
nMerge
S
ϕ
– IndexIndexJoinRule
Wandelt einen algebraischen Join in einen Index-Index-Join um, wenn für
beide Relationen ein Index vorhanden ist.
attrsch(ϕ, R) ∧ attrindex(ϕ, R) ∧ attrsch(ϕ, S) ∧ attrindex(ϕ, S)
⇒Ro
nϕ S := R o
nIndex,Index
S
ϕ
– RelIndexJoinRule
Wandelt einen Join in einen Rel-Index-Join um, wenn für eine der beiden
Relationen ein Index vorliegt.
Fall 1:
¬attrindex(ϕ, R) ∧ attrsch(ϕ, S) ∧ attrindex(ϕ, S)
2.1. PHYSISCHE OPTIMIERUNGSREGELN
9
⇒Ro
nϕ S := R o
nRel,Index
S
ϕ
Fall 2:
attrsch(ϕ, R) ∧ attrindex(ϕ, R) ∧ ¬attrindex(ϕ, S)
⇒Ro
nϕ S := S o
nRel,Index
R
ϕ
– NestedLoopJoinRule
Diese Regel ist auf alle algebraischen Joins anwendbar.
Ro
nϕ S := R o
nNestedLoop
S
ϕ
• [Merge|IndexIndex|RelIndex|NestedLoop]SemijoinRule
– MergeSemijoinRule
Wandelt einen algebraischen Semijoin in einen physischen Merge-Semijoin
um, wenn beide Relationen sortiert vorliegen.
attrsch(ϕ, R) ∧ attrsort(ϕ, R) ∧ attrsch(ϕ, S) ∧ attrsort(ϕ, S)
⇒ R nϕ S := R nMerge
S
ϕ
– IndexIndexSemijoinRule
Wandelt einen algebraischen Semijoin in einen Index-Index-Semijoin um, wenn
für beide Relationen ein Index vorhanden ist.
attrsch(ϕ, R) ∧ attrindex(ϕ, R) ∧ attrsch(ϕ, S) ∧ attrindex(ϕ, S)
⇒ R nϕ S := R nIndex,Index
S
ϕ
– RelIndexSemijoinRule
Fall 1: wandelt einen Semijoin in einen Rel-Index-Semijoin um, wenn für die
Zweite der beiden Relationen ein Index vorliegt.
¬attrindex(ϕ, R) ∧ attrsch(ϕ, S) ∧ attrindex(ϕ, S)
⇒ R nϕ S := R nRel,Index
S
ϕ
Fall 2: wandelt einen Semijoin in einen Index-Rel-Semijoin um, wenn für die
Erste der beiden Relationen ein Index vorliegt.
attrsch(ϕ, R) ∧ attrindex(ϕ, R) ∧ ¬attrindex(ϕ, S)
⇒ R nϕ S := R nIndex,Rel
S
ϕ
– NestedLoopSemijoinRule
Diese Regel ist auf alle algebraischen Semijoins anwendbar.
R nϕ S := R nNestedLoop
S
ϕ
10
KAPITEL 2. PHYSISCHE OPTIMIERUNG
• [Merge|IndexIndex|RelIndex|NestedLoop]AntisemijoinRule
– MergeAntisemijoinRule
Wandelt einen algebraischen Antisemijoin in einen physischen Merge-Antisemijoin
um, wenn beide Relationen sortiert vorliegen.
attrsch(ϕ, R) ∧ attrsort(ϕ, R) ∧ attrsch(ϕ, S) ∧ attrsort(ϕ, S)
Merge
⇒ R nϕ S := R nϕ
S
– IndexIndexAntisemijoinRule
Wandelt einen algebraischen Antisemijoin in einen Index-Index-Antisemijoin
um, wenn für beide Relationen ein Index vorhanden ist.
attrsch(ϕ, R) ∧ attrindex(ϕ, R) ∧ attrsch(ϕ, S) ∧ attrindex(ϕ, S)
Index,Index
⇒ R nϕ S := R nϕ
S
– RelIndexAntisemijoinRule
Fall 1: wandelt einen Antisemijoin in einen Rel-Index-Antisemijoin um, wenn
für die Zweite der beiden Relationen ein Index vorliegt.
¬attrindex(ϕ, R) ∧ attrsch(ϕ, S) ∧ attrindex(ϕ, S)
Rel,Index
⇒ R nϕ S := R nϕ
S
Fall 2: wandelt einen Antisemijoin in einen Index-Rel-Antisemijoin um, wenn
für die Erste der beiden Relationen ein Index vorliegt.
attrsch(ϕ, R) ∧ attrindex(ϕ, R) ∧ ¬attrindex(ϕ, S)
Index,Rel
⇒ R nϕ S := R nϕ
S
– NestedLoopAntisemijoinRule
Diese Regel ist auf alle algebraischen Antisemijoins anwendbar.
NestedLoop
R nϕ S := R nϕ
S
• [Merge|IndexIndex|RelIndex|NestedLoop]UnionRule
Alle hier vorgestellten physischen Vereinigungen arbeiten mit Duplikateneliminierung.
– MergeUnionRule
Wandelt eine algebraische Union in eine physische Merge-Union um, wenn
beide Relationen sortiert vorliegen.
attrsch(ϕ, R) ∧ attrsort(ϕ, R) ∧ attrsch(ϕ, S) ∧ attrsort(ϕ, S)
⇒ R ∪ S := R ∪Merge S
2.1. PHYSISCHE OPTIMIERUNGSREGELN
11
– IndexIndexUnionRule
Wandelt eine algebraischen Union in eine Index-Index-Union um, wenn für
beide Relationen ein Index vorhanden ist.
attrsch(ϕ, R) ∧ attrindex(ϕ, R) ∧ attrsch(ϕ, S) ∧ attrindex(ϕ, S)
⇒ R ∪ S := R ∪Index,Index S
– RelIndexUnionRule
Wandelt eine Union in eine Rel-Index-Union um, wenn für eine der beiden
Relationen ein Index vorliegt.
Fall 1:
¬attrindex(ϕ, R) ∧ attrsch(ϕ, S) ∧ attrindex(ϕ, S)
⇒ R ∪ S := R ∪Rel,Index S
oder Fall 2:
attrsch(ϕ, R) ∧ attrindex(ϕ, R) ∧ ¬attrindex(ϕ, S)
⇒ R ∪ S := S ∪Rel,Index R
– NestedLoopUnionRule
Diese Regel ist auf alle algebraischen Unions anwendbar.
R ∪ S := R ∪NestedLoop S
• [Index|Rel]SelectionRule
– IndexSelectionRule
Wandelt eine vorhandene algebraische Selektion in eine Index-Selektion um,
wenn für das Attribut ein Index existiert.
(#(attr(ϕ)) = 1) ∧ attrindex(ϕ, R)
⇒ σϕ (R) := σϕIndex (R)
– RelSelectionRule
Diese Regel kann alle algebraischen Selektionen behandeln.
σϕ := σϕRel
• ProductRule
Wandelt ein Product in einen Join ohne Bedingung um.
R × S := R o
ntrue S
12
KAPITEL 2. PHYSISCHE OPTIMIERUNG
• DifferenceRule
Wandelt eine Differenz in einen Antisemijoin mit Bedingung um.
R − S := R nϕ BS
Die Bedingung ergibt sich wie folgt:
^
ϕ=
R.A = B.A, mit T := sch(R) ∩ sch(S)
A ∈ T
• IntersectionRule
Wandelt einen Durchschnitt in einen Semijoin mit Bedingung um.
R ∩ S := R nϕ S
Die Bedingung ergibt sich wie folgt:
^
ϕ=
R.A = S.A, mit T := sch(R) ∩ sch(S)
A ∈ T
Kapitel 3
Kostenbasierte Optimierung von
Verbundfolgen
Bei der kostenbasierten Optimierung können unterschiedliche Strategien benutzt werden,
um einen Anfrageplan zu verbessern. Der in diesem Kapitel beschriebene Optimierer verbessert die Abfolge von Verbund-Operationen mit Hilfe dynamischer Programmierung
und der in [VM96] beschriebenen Algorithmen. Er arbeitet auf dem algebraischen Anfragebaum unter Zuhilfenahme der zu den benutzten Relationen gehörenden Statistiken.
Der Algorithmus wurde als Alternative zu dem in [War03] implementierten MinimumSelectivity-Algorithmus gewählt, um eine Möglichkeit zu haben, Lösungen im kompletten
Suchraum zu finden, und diese mit den Lösungen aus dem auf left-deep trees“ einge”
schränkten Suchraum zu vergleichen. Vergleiche an ausgesuchten Beispielen finden sich
im Kapitel 5.
3.1
Problemstellung
Enthält eine vom Benutzer gestellte Anfrage mehrere Verbund-Operationen, so ist in den
meisten Fällen nicht erkennbar, in welcher Reihenfolge die Verbunde optimal ausgeführt
werden. Ein Optimierer muss anhand der ihm vorliegenden statistischen Daten ermitteln,
in welcher Ausführungsreihenfolge die Verbunde die geringsten Kosten verursachen.
Bei der Suche nach optimalen Anfrageplänen kann der Optimierer in den meisten Fällen
aus Zeitgründen nicht alle möglichen Teilbäume untersuchen. Viele Algorithmen schränken daher den Suchraum ein, und betrachten etwa nur left-deep trees“. Der in diesem
”
Kapitel erläuterte Algorithmus hat keine derartigen Beschränkungen, und kann so auch
unter anderem einen bushy tree“ als optimales Ergebnis liefern.
”
13
14
KAPITEL 3. KOSTENBASIERTE OPTIMIERUNG VON VERBUNDFOLGEN
3.2
Optimierung mit dynamischer Programmierung
Im ersten Schritt wird der Algorithmus für kartesische Produkte erläutert, um dann später für Verbund-Operationen erweitert zu werden. Dies ermöglicht einen verständlichen
Einblick in die Arbeitsweise des Algorithmus.
3.2.1
Optimierung von kartesischen Produkten
Um die Vorgehensweise am Beispiel von V × P × S × H zu erklären, benötigt man
zuerst ein einfaches Kostenmodel1 , und die Kardinalitäten der Beispielrelationen. Um das
Beispiel so einfach wie möglich zu halten nehmen wir an, dass eine Basisrelation Kosten
von 0 verursacht. Weiterhin nehmen wir an, dass sich die Kosten eines kartesischen
Produkts aus den einzelnen Kosten der verbundenen Relationen, sowie aus den Kosten
der Operation zusammensetzen:
cost(R) = 0
cost(R1 × R2 ) = cost(R1 ) + cost(R2 ) + κ(R1 , R2 )
R ist hier eine Basisrelation. R1 und R2 können Basisrelationen oder andere Ausdrücke
der Relationenalgebra sein. κ ist die Kostenfunktion für das Produkt der beiden übergebenen Teilausdrücke. In unserem Beispiel ist κ gleich der Kardinalität des Ergebnisses:
κ(R1 , R2 ) = |R1 × R2 |
Die verwendeten Beispielrelationen haben die in Tabelle 3.1 aufgeführten Kardinalitäten.
Relation Kardinalität
P
10
20
S
V
30
H
40
Tabelle 3.1: Die Basisrelationen
Um nun die optimale Ausführungsreihenfolge zu bekommen, benutzt man eine Tabelle
mit vier Spalten. Die erste Spalte enthält eine Menge von Relationen. Die zweite Spalte
enthält die Kardinalität des kartesischen Produkts der Mengenelemente (bei einelementigen Mengen nur die Kardinalität der enthaltenen Basisrelation). Die dritte Spalte enthält
ein Menge mit Relationen, die die geringsten Kosten verursachen, wenn man das Produkt
mit ihnen beginnt (bei Basisrelationen die leere Menge). In der vierten Spalte werden
die Kosten des kartesischen Produkts eingetragen. Die initialisierte Tabelle des Beispiels
findet man unter Tabelle 3.2.
1
siehe hierzu [VM96]
3.2. OPTIMIERUNG MIT DYNAMISCHER PROGRAMMIERUNG
Relation Kardinalität Startmenge
{H}
40
∅
{P}
10
∅
20
∅
{S}
{V}
30
∅
Kosten
0
0
0
0
Tabelle 3.2: Tabelle nach der Initialisierung
3.2.2
Der Algorithmus im Pseudocode
void init_table(Relation R, Metadata M) {
table.add(R, M.getCardinality(R), ∅, 0);
}
void compute_cardinality(Menge S, Metadata M) {
card = 1;
for each p ∈ S do {
card = card · M.getCardinality(p);
}
table.add(S, card, ∅, 0);
}
void optimize(Menge R, Metadata M) {
for each r ∈ R do
init_table(r, M);
for (count=2; count < R.size(); inc(count) {
for each S ⊆ R und |S| = count do {
compute_cardinality(S, M);
find_best_split(S);
}
}
}
void find_best_split(Menge S) {
best cost = MAX VALUE;
for each Slhs , ∅ ⊂ Slhs ⊂ S do{
Srhs = S − Slhs ;
cost = table.getCost(Srhs ) + table.getCost(Slhs ) + κ(Slhs , Srhs );
if (cost < best cost) {
best cost = cost;
table.setLHS(S, Slhs );
}
}
table.setCost(S, best cost);
}
15
16
KAPITEL 3. KOSTENBASIERTE OPTIMIERUNG VON VERBUNDFOLGEN
Die Funktion init_table erstellt eine neue Zeile in der Optimierungstabelle. Die Relation R wird dabei zusammen mit ihrer Kardinalität, einer leere Startmenge und Kosten
von Null eingetragen.
Die Metadaten enthalten die Kardinalitäten der Relationen.
Die Tabelle table speichert die Menge der teilnehmenden Relationen, die Kardinalität
der Operation, die beste Startmenge und die Kosten der Operation. Sie stellt Funktionen
bereit um diese Werte auszulesen oder neu zu setzen. Die Tabelle benutzt die gespeicherte Menge als Primärschlüssel, so dass die anderen Werte über die Menge eindeutig
identifiziert werden.
Die Funktion compute_cardinality(S) berechnet die Kardinalität der Relationenmenge
S wie folgt:
Y
compute_cardinality(S) =
|p|
p∈S
Die Funktion optimize initialisiert erst die Optimierungstabelle mit den Basisrelationen.
Danach werden für jede mögliche Teilmenge S der Menge R der Basisrelationen die
Funktionen compute_cardinality und find_best_split aufgerufen.
Die Funktion find_best_split sucht in der Tabelle für die übergebene Menge die kostengünstigste Startmenge. Diese trägt sie zusammen mit den Kosten in die Tabelle ein.
Für die Berechnungen werden die vorher ermittelten kleineren Teilmengen benutzt, da
diese aufgrund der Arbeitsweise des Algorithmus schon in der Tabelle vorhanden sind.
MAX VALUE ist die größte Zahl, die in der Variablen best cost gespeichert werden
kann.
Aufbau der Tabelle
Im ersten Durchgang werden die Basisrelationen eingetragen. In jedem weiteren Schritt
werden alle möglichen Mengen aus den in der Tabelle gespeicherten Mengen durch Vereinigung gebildet. Diese werden dann jeweils in eine neue Zeile gespeichert und ihre
Kardinalität, die beste Startmenge und die Kosten werden berechnet. Das Verfahren endet sobald eine Menge in die Tabelle eingetragen wurde, die der Menge der am Produkt
beteiligten Relationen entspricht. Die fertige Tabelle für das Beispiel findet sich unter
Tabelle 3.3.
Auswertung der Tabelle
Die optimale Produktreihenfolge läßt sich bestimmen, indem aus der letzten Tabellenzeile die Obermenge R aus der Spalte Relation und die Startmenge S aus der Spalte
Startmenge ausgelesen werden. Nun bildet man das Produkt S × (R − S).
3.2. OPTIMIERUNG MIT DYNAMISCHER PROGRAMMIERUNG
Relation
{H}
{P}
{S}
{V}
{H,P}
{H,S}
{V,H}
{P,S}
{P,V}
{S,V}
{H,P,S}
{H,P,V}
{H,S,V}
{P,S,V}
{H,P,S,V}
Kardinalität Startmenge
40
∅
10
∅
20
∅
30
∅
400
{P }
800
{S}
1200
{V }
200
{S}
300
{V }
600
{V }
8000
{P, S}
12000
{P, V }
24000
{S, V }
6000
{P, S}
240000
{H, P }
17
Kosten
0
0
0
0
400
800
1200
200
300
600
8200
12300
24600
6200
241000
Tabelle 3.3: Tabelle für die Beispielanfrage V × P × S × H
Ist die Startmenge S eine zweielementige Menge {R1 , R2 }, so bildet man aus den beiden
enthaltenen Relationen das Produkt R1 × R2 und ist mit dem linken Teil der Anfrage
fertig. Sollten es mehr als 2 Elemente sein, liest man die Zeile aus der Tabelle, die der
Menge entspricht. Man extrahiert wieder Obermenge und Startmenge und fährt dann
fort wie oben beschrieben. So baut man die linke Seite des Anfragebaums auf. Für die
rechte Seite verfährt man analog, nur startet man hier mit Obermenge minus Startmenge.
Im Beispiel würde man also aus der letzten Zeile die Obermenge {H,P,S,V} und die
Startmenge {H,P} bekommen. Die Startmenge hat nur zwei Elemente, daher ist die
linken Seite des Produkts mit dem Produkt H × P fertig. Die Restmenge ist {H,P,S,V}{H,P}={S,V}. Diese hat auch nur zwei Elemente, daher endet die Abarbeitung hier.
Das Endergebnis ist also (H × P ) × (S × V ).
3.2.3
Erweiterung auf Verbunde
Die Optimierung von Verbund-Operationen ist bis auf die Bildung der Zwischenergebnisse identisch mit der Optimierung von Produkten. Bei der Bildung der Zwischenergebnisse
muss nun die Selektivität der beiden Verbundpartner beachtet werden. Um dieses zu berücksichtigen wird die Tabelle um eine Spalte Selektivität erweitert. In dieser Spalte wird
die Selektivität der Verbundoperation gespeichert.
1
1
,
, mit R = R1 o
nϕ R2 und ϕ ≡ R1 .A = R2 .B
sel(ϕ) = min
#(A, R1 ) #(B, R2 )
Um die Kardinalität von R = R1 o
np R2 zu berechnen, multipliziert man die Kardinalitäten von R1 und R2 mit der Selektivität von p. Da card(R1 ) und card(R2 ) aufgrund
18
KAPITEL 3. KOSTENBASIERTE OPTIMIERUNG VON VERBUNDFOLGEN
der Konstruktionsweise der Tabelle schon enthalten sind, muß nur noch die Selektivität
neu berechnet werden.
Die Selektivität ist das Produkt aller am Verbund beteiligten Selektivitäten. Betrachtet man den Verbund als Graphen mit den Verbundbedingungen als Kanten und den
Relationen als Knoten, so gilt:
R1 o
nϕ R2 mit ϕ =
^
p, P := {p | p spannt R1 und R2 auf}
p∈P
Damit folgt dann die Kardinalität:
card(R) = card(R1 ) · card(R2 ) ·
Y
sel(p), P := {p | p spannt R1 und R2 auf}
p∈P
Da die Selektivität der Verbundpartner schon in der Tabelle gespeichert ist, muss man
nur noch die Gesamtselektivität des neuen Verbundes berechnen. Diese wird dann mit
den anderen Daten gemeinsam in der Tabelle gespeichert.
3.2.4
Neue Kostenfunktion
In diesem Abschnitt wird eine neue Kostenfunktion eingeführt, da die aus der Literatur
entnommene Kostenfunktion (siehe [VM96]) zwar teilweise recht gute Ergebnisse liefert,
aber in einigen Fällen auch erheblich schlechtere Lösungen zulässt. Die neue Funktion
berücksichtigt nun Lesezugriffe über ganze Seiten, und ist damit identisch mit den in
[War03] eingeführten I/O-Kosten.
Die Funktion cost() ist unverändert, da sie die Kosten des Endergebnisses repräsentiert.
cost(R) ist daher immer noch Null, da die Basisrelation schon vorhanden ist, und nicht
erst berechnet werden muss.
Die Funktion κ() wurde wie folgt verändert:
κ(R1 , R2 ) = page(R1 ) + |R1 | · page(R2 )
Die Funktion page(R) liefert die von der Relation R belegten Seiten. Hier bietet sich an,
die Tabelle um eine neue Spalte Seiten zu erweitern. Bei der Initialisierung werden hier
die in den Metadaten gespeicherten Werte eingetragen. Alle weiteren Werte lassen sich
wie folgt berechnen (siehe auch [War03], Kapitel 4.2):
page(R1 op R2 ) = (|R2 | · page(R1 ) + |R1 | · page(R2 )) · sel(R1 op R2 ) , mit op ∈ {×, o
n}
Die neue Tabelle für das Beispiel findet man unter Tabelle 3.4.
3.2. OPTIMIERUNG MIT DYNAMISCHER PROGRAMMIERUNG
Relation
{H}
{P}
{S}
{V}
{H,P}
{H,S}
{H,V}
{P,S}
{P,V}
{S,V}
{H,P,S}
{H,P,V}
{H,S,V}
{P,S,V}
{H,P,S,V}
Kardinalität Seiten Startmenge
40
4
∅
10
1
∅
20
2
∅
30
3
∅
400
80
{P }
800
160
{S}
1200
240
{V }
200
40
{P }
300
60
{P }
600
120
{S}
8000
2400
{P, S}
12000
3600
{P, V }
24000
7200
{S, V }
6000
1800
{P, S}
240000
96000
{P, S, V }
19
Kosten
0
0
0
0
41
82
123
21
31
62
861
1291
2582
661
26461
Tabelle 3.4: Neue Tabelle für die Beispielanfrage V × P × S × H
3.2.5
Beispiel mit Verbunden
In diesem Abschnitt findet sich die Tabelle für folgende kurze Anfrage:
V o
n (H o
n S)
Dafür benötigen wir Attribute sowie die Anzahl unterschiedlicher Tupel pro Attribut.
Diese finden sich in Tabelle 3.5
Relation Kardinalität Attribute
S
20
{A, B}
V
30
{C,D}
H
40
{A,C}
n(A,R)
A=20, B=6
C=30, D=10
A=20, C=30
Tabelle 3.5: Erweiterte Basisrelationen
Die fertige Optimierungstabelle findet sich unter Tabelle 3.6.
3.2.6
Behandlung von Selektionen
Um noch bessere Ergebnisse erzielen zu können, wurde der Optimierer in einem letzten
Schritt so erweitert, dass er neben Basisrelationen auch Selektionen mit in seine Berechnungen einbezieht. Selektionen werden wie normale Basisrelationen behandelt. In die
Optimierungstabelle wird die Kardinalität des Ergebnisses und die Anzahl der belegten
20
KAPITEL 3. KOSTENBASIERTE OPTIMIERUNG VON VERBUNDFOLGEN
Relation Kardinalität Seiten Startmenge
{H}
40
4
∅
{S}
20
2
∅
30
3
∅
{V}
{H,S}
40
8
{S}
{H,V}
40
8
{V }
600
120
{S}
{S,V}
{H,S,V}
40
12
{S, V }
Kosten Selektivität
0
1
0
1
0
1
82
0,05
123
0,033
62
1
210
0,002
Tabelle 3.6: Tabelle für die Beispielanfrage V o
n (H o
n S)
Seiten eingetragen. Um Selektionen in der Tabelle von Basisrelationen unterscheiden zu
können, bekommen sie als Präfix das Zeichen σ gefolgt von dem Namen der Relation,
auf die sich die Selektion bezieht.
Während der Tabelleninitialisierung muss darauf geachtet werden, dass alle vorkommenden Selektionen unter dem Namen in einer neuen Datenstruktur gespeichert werden, mit
dem sie in die Tabelle eingetragen werden. Dies ist nötig, da in der Tabelle die Bedingungen nicht mit gespeichert werden. Nach der Optimierung kann man dann die Selektionen
mit ihren Bedingungen aus dieser Datenstruktur auslesen und in den neuen Anfragebaum
einfügen.
Beispiel mit Selektion
Das Beispiel aus Kapitel 1 erzeugt die Tabelle 3.7. Hier sieht man, dass die Selektion auf
S in der Tabelle als σS aufgeführt wird und so in die Berechnung eingeht.
Relation
{H}
{P}
{V}
{σS}
{H,P}
{H,V}
{H,σS}
{P,V}
{P,σS}
{V,σS}
{H,P,V}
{H,P,σS}
{H,V,σS}
{P,V,σS}
{H,P,V,σS}
Kardinalität Seiten Startmenge
40
4
∅
10
1
∅
30
3
∅
3
1
∅
400
80
{P }
40
8
{V }
6
3
{σS}
30
6
{P }
30
13
{σS}
90
39
{σS}
40
12
{P, V }
60
36
{H, σS}
6
4
{H, σS}
90
48
{σS}
6
5
{H, V, σS}
Kosten Selektivität
0
1
0
1
0
1
0
1
41
1
123
0,033
13
0,05
31
0,1
4
1
10
1
157
0,003
22
0,05
34
0,002
50
0,1
44
0,0002
Tabelle 3.7: Optimierungstabelle für die Beispielanfrage aus Kapitel 1
Kapitel 4
Anbindung an die Oracle-Datenbank
In diesem Kapitel wird die Anbindung von RELOpt an die Datenbank Oracle 9i/10g
beschrieben. Über diese Schnittstelle soll dem Benutzer die Möglichkeit gegeben werden,
Relationen und ihre Attribute, sowie die entsprechenden Statistiken aus der Datenbank
zu übernehmen. Dies erleichtert die Benutzung, da man nicht erst alle Relationen per
Hand eingeben muss.
RELOpt wurde daher so erweitert, dass es diese Metadaten aus den über JDBC zur
Verfügung gestellten Metadaten, sowie direkt aus den in der Datenbank gespeicherten
Metadatenrelationen auslesen kann.
4.1
Importieren von Tabellen
Abbildung 4.1: Die Knöpfe im Hauptfenster von RELOpt
Die Importfunktion für Tabellen und ihre Attribute ist im Hauptfenster von RELOpt
unter dem Knopf Metadaten zu finden (siehe Abb. 4.1). Dort wurde ein neuer Knopf
Tabellen aus Datenbank übernehmen hinzugefügt (Abb. 4.2).
21
22
KAPITEL 4. ANBINDUNG AN DIE ORACLE-DATENBANK
Abbildung 4.2: Dialog für die Bearbeitung von Tabellen
Wird der Knopf Tabellen aus Datenbank übernehmen gedrückt, werden die Tabellen aus
dem Benutzerschema des an der Datenbank angemeldeten Benutzer ausgelesen und in
der Auswahltabelle (Abb. 4.4) dargestellt. Sollte noch keine Verbindung zur Datenbank
bestanden haben, wird vorher ein Verbindungsdialog angezeigt (Abb. 4.3) und versucht
mit den eingegebenen Daten eine Verbindung aufzubauen.
Abbildung 4.3: Dialog für den Datenbanklogin
Der Nutzer kann nun in der Auswahltabelle die gewünschten Tabellen markieren und per
Knopfdruck auf Tabellen hinzufügen importieren. Soll eine Tabelle aus einem anderen
Schema übernommen werden, so kann man dieses in das Eingabefeld Schema eingeben.
Nach einem Klick auf Schema laden erscheinen dann die Tabellen des ausgewählten
Schemas in der Auswahltabelle. Die Eingabe darf die Oracle Wildcards _ und % enthalten.
Sollten mehrere Schemas auf diese Eingabe passen, so werden alle Tabelle aus allen
passenden Schemas geladen.
4.2. IMPORTIEREN VON STATISTIKEN
23
Abbildung 4.4: Dialog für den Import von Tabellen
4.2
Importieren von Statistiken
Die statistischen Daten der importierten Relationen werden automatisch mit eingelesen.
Die Kardinalitäten werden aus den von der JDBC-Schnittstelle gelieferten Metadaten
gewonnen, ebenso mögliche Indexe. Aufgrund des Rechtemanagements kann beim Import von Fremdtabellen aus anderen Schemata nicht immer auf die durch die JDBCSchnittstelle gelieferten Metadaten zurückgegriffen werden. Daher werden in so einem
Fall die Metadaten nicht automatisch übernommen, sondern müssen vom Benutzer eingetragen werden. Hierbei erfolgt eine Meldung wenn beim Import Nullwerte eingelesen
wurden.
Die Klasse DBManager stellt sowohl die Metadaten der JDBC-Schnittstelle zur Verfügung als auch Daten die durch direkte Anfragen an die Datenbank gewonnen wurden.
Die angesprochenen Relationen sind nachfolgend aufgezählt.
• ALL_TABLES
Aus dieser Relation wird die Seiten- und Tupelkardinalität ausgelesen.
• ALL_TAB_COLUMNS
Aus dieser Relation wird die Anzahl der eindeutigen Tupel #(A, R) ausgelesen.
• ALL_INDEXES
Aus dieser Relation werden die Indexe gewonnen, sowie die zugehörigen Kardinalitäten.
• ALL_IND_COLUMNS
Aus dieser Relation wird die Zuordnung der Indexe zu den einzelnen Spalten ausgelesen.
24
KAPITEL 4. ANBINDUNG AN DIE ORACLE-DATENBANK
• PLAN_TABLE
In dieser Tabelle speichert das Oracle-System die Anfragepläne, die durch die Anweisung EXPLAIN PLAN FOR <SQL ANFRAGE> angefordert werden.
4.3
Import von Anfrageplänen
Um eine Anfrage durch das Oracle-System bewerten zu lassen wird die vom Benutzer
erstellte Anfrage durch einen Übersetzer in ein SQL-Statement umgewandelt. Die vom
Übersetzer gelieferte SQL-Anfrage wird über die JDBC-Schnittstelle an die Datenbank
übergeben. Der dort erstellte Anfrageplan wird dann zurückgegeben und in einem Anzeigefenster dargestellt. Eine Erweiterungsmöglichkeit wäre hier die Visualisierung des
von der Datenbank gelieferten Plans (Siehe Kap. 7).
4.3.1
Der Übersetzer
Der Übersetzer hat die Aufgabe, aus dem von RELOpt gelieferten Anfrageplan eine für
die Oracle-Datenbank verständliche SQL-Anfrage zu generieren. Hierfür durchläuft er
die Anfrage und wendet auf die einzelnen Teile verschiendene Regeln an.
4.3.2
Die Regeln
Insgesamt gibt es 10 Regel, die die Bearbeitung der Anfrage übernehmen. Die hier benutzten Regeln für abgeleiteten Operationen stammen aus [Lip03]:
• JoinSQLRule
Diese Regel formt einen Join R o
nϕ S in folgenden SQL Ausdruck um:
SELECT * FROM R ALIAS JOIN S ALIAS ON (ϕ̄)
Hierbei wurde ϕ in ϕ̄ umgewandelt, indem die entsprechenden Relationen durch
die zugehörigen Aliase ersetzt wurden.
• SemijoinSQLRule
Da für Semijoins folgendes gilt:
R nϕ S = R o
nϕ πAttribute(R) (S)
folgt für die Anfrage in SQL:
SELECT R.* FROM R JOIN S ON (ϕ)
4.3. IMPORT VON ANFRAGEPLÄNEN
25
Bei dieser Anfrage kann das Oracle-System aber nicht erkennen, dass es sich um
einen Semijoin handelt. Daher wird der Semijoin in folgende Anfrage übersetzt,
welche korrekt erkannt wird:
SELECT * FROM R ALIAS
WHERE EXISTS
(SELECT * FROM S ALIAS WHERE (ϕ̄))
Hierbei wurde ϕ in ϕ̄ umgewandelt, indem die entsprechenden Relationen durch
die zugehörigen Aliase ersetzt wurden.
• AntisemijoinSQLRule
Diese Regel benutzt folgenden Sachverhalt, um einen Antisemijoin in SQL darzustellen:
R nϕ S = R − R o
nϕ πAttribute(R) (S)
Dies kann in SQL wie folgt realisiert werden:
(SELECT * FROM R)
MINUS
(SELECT R.* FROM R JOIN S ON (ϕ))
Bei dieser Anfrage kann das Oracle-System aber nicht erkennen, dass es sich um
einen Antisemijoin handelt. Daher wird der Antisemijoin in folgende Anfrage übersetzt, welche korrekt erkannt wird:
SELECT * FROM R ALIAS
WHERE NOT EXISTS
(SELECT * FROM S ALIAS WHERE (ϕ̄))
Hierbei wurde ϕ in ϕ̄ umgewandelt, indem die entsprechenden Relationen durch
die zugehörigen Aliase ersetzt wurden.
• DifferenceSQLRule
Diese Regel formt die Differenz R − S in folgendes SQL Statement um:
(SELECT * FROM R)
MINUS
(SELECT * FROM S)
• IntersectionSQLRule
Diese Regel formt den Durchschnitt R ∩ S in folgendes SQL Statement um:
(SELECT * FROM R)
INTERSECT
(SELECT * FROM S)
• UnionSQLRule
Diese Regel formt die Vereinigung R ∪ S in folgendes SQL Statement um:
(SELECT * FROM R)
UNION
(SELECT * FROM S)
26
KAPITEL 4. ANBINDUNG AN DIE ORACLE-DATENBANK
• ProductSQLRule
Diese Regel formt das Produkt R × S in folgendes SQL Statement um:
SELECT * FROM R CROSS JOIN S
• ProjectionSQLRule
Diese Regel formt die Projektion πĀ (R) in folgendes SQL Statement um:
SELECT Ā FROM R
• SelectionSQLRule
Diese Regel formt die Selektion σϕ (R) in folgendes SQL Statement um:
SELECT * FROM R WHERE (ϕ)
• TableSQLRule
Diese Regel fügt dem SQLStatement den Namen der Tabelle als neue Relation
hinzu.
4.4
Anfrageplanerstellung in der Oracle Datenbank
Zuerst wird in der Oracle Datenbank geprüft, ob eine Relation PLAN TABLE existiert.
In dieser Relation speichert der Oracle-Optimierer den von ihm erstellten Anfrageplan.
Ist diese Relation vorhanden, so wird sie geleert. Sollte dies nicht der Fall sein, wird diese
angelegt.
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------| Id | Operation
| Name
| Rows | Bytes | Cost |
-----------------------------------------------------------------------|
0 | SELECT STATEMENT
|
|
51 | 1734 |
1 |
|
1 | NESTED LOOPS
|
|
51 | 1734 |
1 |
|
2 |
INDEX FULL SCAN
| PK_ADMIN_PR_VP |
56 | 1008 |
1 |
|* 3 |
INDEX UNIQUE SCAN | PK_PRES
|
1 |
16 |
|
-----------------------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------3 - access("ADMIN_PR_VP"."VICE_PRES_NAME"="PRESIDENT"."PRES_NAME")
Note: cpu costing is off
Abbildung 4.5: Oracle Anfrageplan
PLAN TABLE wird standardmäßig vom SQL Befehl EXPLAIN PLAN FOR benutzt, um
einen Anfrageplan abzuspeichern. Nachdem der Benutzer die Anfrage abgeschickt hat,
4.5. IMPLEMENTIERUNG
27
wird das Ergebnis mit folgendem SQL Befehl ausgelesen und auf der rechten Seite des
Dialogs dargestellt.
SELECT * FROM TABLE ( DBMS_XPLAN.display() );
DBMS_XPLAN wird von der Oracle Datenbank zur Verfügung gestellt, um Anfragepläne
übersichtlich als Textausgabe darzustellen. Das Paket hat nur eine einzige Prozedur
namens display(). Das Beispiel aus Kapitel 1 ist in Abbildung 4.5 zu sehen. Man sieht,
dass der Oracle-Optimierer die Tupel mit Index Zugriffen auswählt, und dann mit einem
Nested-Loop-Verbund zusammenführt.
4.5
Implementierung
In diesem Abschnitt wird die Implementierung der Importschnittstelle und die Anwendung der neuen Klassen beschrieben. Die Klassen verwenden für die Datenbankzugriffe
JDBC, welches über das Paket java.sql benutzt wird. Die für die Implementierung zu
Rate gezogenen Oracle-Dokumentationen finden sich unter [ORA].
4.5.1
Klassen
Um die oben skizzierten Funktionen in RELOpt bereitzustellen, wurde ein neues Paket
sopt.db.oracle angelegt. Dieses enthält die nachfolgenden Klassen.
• DBManager
Diese Klasse verwaltet die Verbindung zur Datenbank. Sie stellt eine Methode
bereit, die die Verbindung zur Datenbank liefert. Sollte die Verbindung noch nicht
bestehen, wird ein JLoginDialog geöffnet. Mit den vom Benutzer gelieferten Logindaten wird dann versucht, eine Verbindung zur Datenbank herzustellen.
Desweiteren stellt sie Methoden zum Schließen der Verbindung und zur Abfrage
der Metadaten bereit. Auch die Anfragepläne werden von dieser Klasse aus der
Datenbank gelesen. Für Metadaten, die nicht aus den von JDBC gelieferten Daten gewonnen werden können, werden PreparedStatement bereitgestellt. Diese
Anfragen werden zur Laufzeit generiert, sobald sie das erste Mal benutzt werden.
– openConnection
Stellt die Verbindung zur Datenbank her.
– getConnection
Liefert ein Objekt vom Typ Connection.
28
KAPITEL 4. ANBINDUNG AN DIE ORACLE-DATENBANK
– closeConnection
Schliesst die Verbindung, wenn sie noch offen ist.
– getMetaData
Liefert die Datenbankmetadaten.
– sendStatement
Sendet die übergebene Anfrage an die Datenbank.
– sendQuery(String statement
Sendet die übergebene Anfrage an die Datenbank und liefert das Ergebnis
zurück.
– preparePlanTable
Schaut nach, ob die Relation PLAN_TABLE existiert, wenn nicht wird diese
angelegt.
– getPlan
Fragt die Relation PLAN_TABLE ab und liefert das Ergebnis.
– getTableInfo
Liefert Tupel- und Seiten-Kardinalitäten der übergebenen Relation.
– getNumDistinct
Liefert die Spaltennamen und die Anzahl der einzigartigen Tupel in der jeweiligen Spalte.
– getIndexes
Liefert alle Spalten, die mit einem Index versehen sind.
– isClosed
Liefert wahr, wenn die Verbindung getrennt ist.
• SQLStatement
Diese Klasse repräsentiert eine SQL Anfrage. Sie stellt Methoden zum Hinzufügen
vom Selektionsbedingungen, Relationen und Projektionsbedingungen zur Verfügung. Ihre toString() Methode liefert eine Anfrage der Form EXPLAIN PLAN FOR
SELECT..., die direkt an die Datenbank geschickt werden kann.
– addAttribute
Fügt ein Attribut hinzu.
– addRelation
Fügt eine Relation hinzu.
– addCondition
Fügt eine Bedingung hinzu.
– toString
Liefert eine Stringdarstellung der SQL-Anfrage.
4.5. IMPLEMENTIERUNG
29
• StatementBuilder
Diese Klasse erzeugt aus einem algebraischen Baum eine äquivalente SQL Anfrage.
Diese wird benötigt um die Anfrage des Benutzers durch das Oracle System bewerten zu lassen. Der StatementBuilder erwartet als Eingabe einen AlgebraicTree.
Diesen durchläuft er dann von oben nach unten (TopDown) und liefert am Ende
ein Objekt vom Typ SQLStatement (s.o.), dass die Anfrage in SQL repräsentiert.
– createStatement
Erstellt ein SQL Statement aus dem übergebenen AlgebraicTree oder der
übergebenen Relation.
– conditionToSQL
Liefert die übergebene Bedingung vom Typ Condition als String.
– createCondition
Fügt dem übergebenen SQLStatement eine Stringdarstellung der übergebenen
Condition hinzu.
Das Paket dbs.sopt.gui wurde um folgende Klassen erweitert, welche die grafische
Benutzerschnittstelle der Anbindung zur Verfügung stellen.
• DBImport
DBImport fordert über den DBManager die Metadaten der Datenbank an und stellt
dem Benutzer die gefundenen Relationen mit ihren Attributen zum Importieren in
RELOpt zur Verfügung. Für alle importierten Relationen werden, wenn vorhanden,
die Kardinalitäten und weitere Metadaten ausgelesen und in die von RELOpt
gespeicherten Daten integriert.
• SendSQLToDB
Diese Klasse ist eine Erweiterung von JDialog. Der Dialog enthält in der oberen
Hälfte die vom StatementBuilder erstellte Anfrage. Darunter befinden sich links
die Darstellung des Anfrageplans, wie RELOpt ihn erstellt hat, und auf der rechten
Seite wird der Anfrageplan der Oracle Datenbank dargestellt (siehe Abb. 4.9).
Der Oracle Anfrageplan steht zur Verfügung, sobald der Benutzer auf Abschicken
geklickt hat. Der Dialog schickt dann die Anfrage zur Datenbank und liest den
Anfrageplan aus der Tabelle PLAN_TABLE.
4.5.2
Die Regeln
Die Oberklasse aller Übersetzerregeln ist die abstrakte Klasse SQLRule (siehe Abbildung
4.6). Sie definiert 2 Methoden die von den Subklassen überschrieben werden müssen.
Die Auslagerung der Übersetzerregeln in eigene Klassen wurde in Hinblick auf spätere
Erweiterungen des Sprachumfangs gewählt. So können neue Sprachkonstrukte durch
einfaches Erstellen einer passenden Regel und eines Eintrags in der Regel-Hash-Map
integriert werden.
30
KAPITEL 4. ANBINDUNG AN DIE ORACLE-DATENBANK
• handlesClass
Diese Methode liefert ein Objekt vom Typ Class zurück. Es repräsentiert die Art
von Klasse, die diese Regel behandeln kann.
• create
Diese Methode erwartet als Parameter eine Relation und ein SQLStatement. Sie
liefert das SQLStatement zurück, erweitert um die SQL-Darstellung der Relation.
SQLRule
handleClass
create
Product
SQLRule
Join
SQLRule
Intersection
SQLRule
Semijoin
SQLRule
Union
SQLRule
Antisemijoin
SQLRule
Difference
SQLRule
Projection
SQLRule
Table
SQLRule
Selection
SQLRule
Abbildung 4.6: Ausschnitt aus dem Paket sopt.sqlp.rules
4.5.3
Der Übersetzer
Der Übersetzer besteht aus der Hauptklasse StatementBuilder und den in Abschnitt
4.3.2 definierten Regeln. Der Übersetzer erwartet als Eingabe einen Anfragebaum. Dieser
wird dann rekursiv durch die Regeln durchlaufen. Als Ergebnis liefert der Übersetzer die
SQL-Anfrage als Text. Der Aufruf des Übersetzer geschieht durch die statische Methode
createStatement. Diese erwartet als Eingabe einen AlgebraicTree und liefert einen
String zurück, der die Anfrage in SQL darstellt.
Funktionsweise
Der Übersetzer benutzt für die Umwandlung der im AlgebraicTree gespeicherten Objekte vom Typ Relation (In RELOpt haben alls Operationen Relation als Superklasse)
eine Reihe von Regeln, die dynamisch zur Laufzeit ausgewählt werden.
4.5. IMPLEMENTIERUNG
31
Um ein Objekt zu übersetzen, wird zuerst in einer HashMap nachgeschaut, welche Regel für diese Art von Objekten zuständig ist. Dabei wird die Klasse des Objekts als
Schlüssel benutzt. Danach wird über die in Java eingebauten Reflektionsmethoden die
statische Methode create der Regel aufgerufen. Die Regel extrahiert die Operation, die
Teilbäume, auf die die Operation angewendet wird, und gegebenenfalls eine Bedingung.
Mit diesen Informationen wird dann das der Regel übergebene SQLStatement erweitert.
Danach wird auf jeden Teilbaum erneut der StatementBuilder aufgerufen.
Handelt es sich bei der Operation um Join, Semijoin oder Antisemijoin, so werden
Aliase für die Teilbäume eingeführt. Der Alias setzt sich aus dem Namen der Wurzel des
Teilbaumes sowie des Hashwert der Wurzel zusammen. In der Bedingung werden dann
alle Relationennamen durch den entsprechenden Alias ersetzt.
Der Übersetzer am Beispiel
Der Übersetzer liefert für den in Abbildung 4.7 gezeigten Anfragebaum das in Abbildung
4.8 gezeigte SQL-Statement.
πP.N ame,
S.Semester
⋊
⋉P.ID=V.gelesenV on
P
⋊
⋉V.V orlN r=H.V orlN r
V
⋊
⋉H.MatrN r=S.MatrN r
H
S
Abbildung 4.7: Beispielanfragebaum für den SQL-Übersetzer
SELECT Name, Semester
FROM P P10592665
JOIN (SELECT *
FROM V V1685884
JOIN (SELECT *
FROM H H6839856
JOIN S S16766291 ON (H6839856.MatrNr=S16766291.MatrNr)
) JOIN14722034 ON (V1685884.VorlNr=JOIN14722034.VorlNr)
) JOIN7893316 ON (P10592665.ID=JOIN7893316.gelesenVon)
Abbildung 4.8: Beispielanfrage in SQL
32
4.5.4
KAPITEL 4. ANBINDUNG AN DIE ORACLE-DATENBANK
Die Benutzerschnittstelle
Die Klasse des Vergleichsfensters ist SendSQLToDB. Ein Bild des Fensters ist unter Abbildung 4.9 zu finden. Im oberen Teil des Fensters kann der Benutzer seine Anfrage sehen,
die an die Datenbank geschickt wird. Auf der unteren linken Seite findet der User den von
RELOpt erstellten Anfrageplan, auf der unteren rechten Seite die Version des verwendeten Oracle-Systems. Die Erstellung der SQL-Statements wird durch die in Kapitel 4.5.1
beschriebene Klasse StatementBuilder realisiert. Die Ausgabe des StatementBuilders
wird in der oberen Hälfte des SendSQLToDB Dialogs dargestellt.
Abbildung 4.9: Dialog für den Anfrageplan Vergleich
Kapitel 5
Experimente und Anwendungen
In diesem Kapitel finden sich Vergleiche zwischen dem in [War03] implementierten
Minimum-Selektivity-Algorithmus und dem in dieser Arbeit behandelten Join-OrderAlgorithmus. Weiterhin werden hier beispielhaft Unterschiede und Gemeinsamkeiten
zwischen RELOpts Optimierung und der Optimierung einer Orcale-Datenbank aufgeführt.
5.1
Vergleich Join-Order mit Minimum-Selektivity
Da der Join-Order-Algorithmus (im folgenden kurz JOA) Lösungen im kompletten Suchraum findet, ist es interessant, diese mit den vom Minimum-Selektivity-Algorithmus (im
folgenden kurz MSA) gefundenen Lösungen zu vergleichen. Besonders interessant sind
hier Lösungen des JOA, die nicht im Suchraum des MSA liegen. Zum Beispiel Anfragepläne in Form von bushy-trees“ oder right-deep-trees“.
”
”
5.1.1
Beispiele in Form von left-deep-trees“
”
Für eine Vielzahl von Anfragen liefern beide Algorithmen identische Lösungen. Als Beispiel dieser Gruppe von Anfragen dient folgende aus Kapitel 1 bekannte Anfrage:
(PROJECTION P.Name
(SELECTION S.Semester=’5’
(JOIN P.ID=V.gelesenVon P
(JOIN V.VorlNr=H.VorlNr V
(JOIN H.MatrNr=S.MatrNr H S)))))
33
34
KAPITEL 5. EXPERIMENTE UND ANWENDUNGEN
Sowohl der JOA als auch der MSA liefern den in Abbildung 5.1 gezeigten Anfragebaum.
πP.Name
σS.Semester =’5’
⋊
⋉H.MatrNr =S.MatrNr
S
⋊
⋉V.VorlNr =H.VorlNr
⋊
⋉P.ID =V.gelesenVon
P
H
V
Abbildung 5.1: Anfragebaum der Beispielanfrage (JOA/MSA)
Führt man vor der Optimierung die entsprechenden Regeln aus, um die Selektion nach
unten in den Anfragebaum zu schieben, ergibt sich die Lösung in Abbildung 5.2, wieder
identisch für beide Optimierer.
πP.Name
⋊
⋉P.ID =V.gelesenVon
⋊
⋉V.VorlNr =H.VorlNr
⋊
⋉H.MatrNr =S.MatrNr
σS.Semester =’5’
P
V
H
S
Abbildung 5.2: Anfragebaum der Beispielanfrage mit verschobener Selektion
5.1.2
Fazit
Bei allen getesteten Anfragen1 lieferten beide Optimierer identische Ergebnisse. Für
keine der durch den JOA optimierten Anfragen wurde ein bushy-tree“ oder right-deep”
”
tree“ geliefert. Dies lässt darauf schliessen, dass die beim Minimum-Selektivity getroffene
Einschränkung auf das Gebiet der left-deep-trees“ gerechtfertigt ist.
”
1
hier größtenteils nicht dargestellt
5.2. OPERATIONEN DER ORACLE-DATENBANK
5.2
35
Operationen der Oracle-Datenbank
Um die von der Oracle-Datenbank gelieferten Anfragepläne mit denen von RELOpt
vergleichen zu können, müssen zuerst für die von der Oracle-Datenbank benutzten Operationen äquvalente Operationen in RELOpt aufgeführt werden.
5.2.1
Struktur der Oracle-Anfragen
Das Wurzelelement des Anfragebaums, der aus der Oracle-Datenbank über die Relation PLAN_TABLE ausgelesen werden kann, ist immer vom Typ SELECT STATEMENT. Alle
weiteren Elemente des Anfragebaums sind beliebige Operationen. Diese können mehrere
Kindelemente und Optionen haben.
Das Beispiel aus Kapitel 1 hat den in Abbildung 5.3 dargestellten Anfragebaum. Die
Abkürzung T. steht für TABLE.
SELECT STATEMENT
NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
T. ACCESS BY INDEX ROWID
INDEX UNIQUE SCAN
INDEX FULL SCAN
INDEX RANGE SCAN
P ID PK
H VORLNR MATRNR PK
V VORLNR PK
T. ACCESS FULL
S
T. ACCESS BY INDEX ROWID
Abbildung 5.3: Anfragebaum des Beispiels aus Kapitel 1
5.2.2
Umsetzung der Oracle-Operationen in RELOpt
In der Tabelle 5.1 finden sich die von Oracle benutzten Operationen und ihre äquivalenten
Umsetzungen in RELOpt, wenn vorhanden. Die drei Operationen NESTED LOOPS, MERGE
JOIN und HASH JOIN können die Option OUTER haben. Da RELOpt keine Outer-Joins
unterstützt, können Operationen mit dieser Option nicht in RELOpt dargestellt werden.
Weiterhin können die Joins als CARTESIAN (z.B. MERGE JOIN CARTESIAN) auftreten. Diese lassen sich in RELOpt durch den entsprechenden Verbund mit der Bedingung TRUE
darstellen. Die Bedingung TRUE liefert immer wahr.
36
KAPITEL 5. EXPERIMENTE UND ANWENDUNGEN
In der Tabelle steht * für einen Wildcard, nicht unterstützt bedeutet, das diese Funktion
in RELOpt nicht darstellbar ist. INDEX bedeutet, dass die Tupel über einen Indexzugriff
geholt werden, TABLE ACCESS steht für den direkten Tupelzugriff.
Die Spalte Operation enthält die vom Oracle-Sytem benutzten Operationen. In den beiden Spalten 1. Kindelement und 2. Kindelement werden die im Anfragebaum möglichen
Kindelemente aufgeführt.
Neben den in der Tabelle aufgeführten Operationen TABLE ACCESS und INDEX sind noch
verschiedene Sortierungen SORT möglich, diese als Kindelemente mit aufzuführen würde
aber den Rahmen der Tabelle sprengen. In der Spalte Darstellung in RELOpt werden
die Java-Klassen aufgeführt, mit denen man die Oracle-Operation möglichst äquivalent
in RELOpt darstellen kann.
Operation
1. Kindelement 2. Kindelement Darstellung in RELOpt
NESTED LOOPS
TABLE ACCESS
TABLE ACCESS
NestedLoopJoin
TABLE ACCESS
INDEX
RelIndexJoin
INDEX
TABLE ACCESS
RelIndexJoin
INDEX
INDEX
IndexIndexJoin
MERGE JOIN
TABLE ACCESS
TABLE ACCESS
MergeJoin
TABLE ACCESS
INDEX
nicht unterstützt
INDEX
TABLE ACCESS
nicht unterstützt
INDEX
INDEX
nicht unterstützt
HASH JOIN
TABLE ACCESS
TABLE ACCESS
HashJoin
TABLE ACCESS
INDEX
nicht unterstützt
INDEX
TABLE ACCESS
nicht unterstützt
INDEX
INDEX
nicht unterstützt
UNION
TABLE ACCESS
TABLE ACCESS
NestedLoopUnion
TABLE ACCESS
INDEX
RelIndexUnion
INDEX
TABLE ACCESS
RelIndexUnion
INDEX
INDEX
IndexIndexUnion
MINUS
TABLE ACCESS
TABLE ACCESS
NestedLoopAntisemijoin
TABLE ACCESS
INDEX
RelIndexAntisemijoin
INDEX
TABLE ACCESS
IndexRelAntisemijoin
INDEX
INDEX
IndexIndexAntisemijoin
INTERSECTION
TABLE ACCESS
TABLE ACCESS
NestedLoopSemijoin
TABLE ACCESS
INDEX
RelIndexSemijoin
INDEX
TABLE ACCESS
IndexRelSemijoin
INDEX
INDEX
IndexIndexSemijoin
SORT
*
AttrSort
Tabelle 5.1: Oracle-Operationen und ihre Umsetzung in RELOpt
5.3. VERGLEICHE MIT DER ORACLE-DATENBANK
5.3
5.3.1
37
Vergleiche mit der Oracle-Datenbank
Beispielanfrage ohne Selektion
Das Ergebnis der Optimierung der aus Kapitel 1 und 4.5.3 bekannten Beispielanfrage
(siehe Abbildung 1.1) nach der Optimierung durch RELOpt ist in Abbildung 5.4 zu
finden. Bei der Anfrage wurde die Selektion weggelassen. In Abbildung 5.5 findet sich
der Anfragebaum nach der Optimierung durch das Oracle-System. Im Oracle-System
wurden vorher die Statistiken der benutzten Beispielrelationen mit den entsprechenden
Systemfunktionen gesammelt.
Index/elim
S.Semester (3)
πP.Name
Tree(P.Name)(33)
⋊
⋉Hash
H.MatrN r=S.MatrN r (9)
Hash(·)
Hash(·)
⋊
⋉Hash
V.V orlN r=H.V orlN r (6)
S
Hash(·)
Hash(·)
⋊
⋉Hash
P.ID=V.gelesenV on (3)
H
Hash(·)
Hash(·)
V
P
Abbildung 5.4: Beispielanfrage durch RELOpt optimiert
In den beiden Anfragebäumen kann man feststellen, dass die grundlegende Struktur und
die Reihenfolge der Verbunde identisch sind. Auch die Art der Verbunde ist in beiden
Anfragebäumen gleich. ein Unterschied ist der Rel-Index-Hash-Verbund mit der Relation
H. Die Oracle-Datenbank greift hier auf den Index H VORLNR MATRNR PK zu.
Da ein Rel-Index-Hash-Verbund in RELOpt nicht implementiert ist, wird in der Lösung
von RELOpt ein normaler Rel-Rel-Hash-Verbund benutzt.
Ein weiterer Unterschied könnte das Wurzelelement der beiden Anfragebäume sein, da
aus der Oracle-Datenbank keinerlei Informationen über die Art der verwendeten Projektion zu bekommen sind. RELOpt bildet hier einen sortierten Indexbaum über die Er-
38
KAPITEL 5. EXPERIMENTE UND ANWENDUNGEN
πP.NameS.Semester (10)
⋊
⋉Hash
H.MatrN r=S.MatrN r (10)
⋊
⋉Hash
V.V orlN r=H.V orlN r (7)
⋊
⋉Hash
P.ID=V.gelesenV on (5)
TABLE ACCESS FULL
INDEX FULL SCAN
TABLE ACCESS FULL
TABLE ACCESS FULL
P
V
S
H VORLNR MATRNR PK
Abbildung 5.5: Beispielanfrage durch Oracle optimiert
gebnisrelation und führt dann eine Index-Projektion mit Duplikateneliminierung durch.
Aus dem PLAN_TABLE lassen sich keine Informationen über die Verwendung von Pipelines extrahieren. Die Form des Oracle-Anfragebaumes lässt aber auf deren Verwendung
schliessen.
5.3.2
Beispielanfrage mit Selektion
Fügt man der Anfrage eine Selektion hinzu, unterscheiden sich die beiden Anfragepläne
erheblich in den verwendeten Verbunden. Als Beispiel dient wieder die aus Kapitel 1 bekannte Anfrage. Diese unterscheidet sich von der vorhergehenden nur durch die Selektion
S.Semester = 5, die im ersten Beispiel weggelassen wurde. In der von RELOpt gelieferten Lösung in Abbildung 5.6 sieht man deutlich, dass die Selektion sehr früh ausgeführt
wird und sich damit die Reihenfolge der Verbunde verändert hat.
Die von Oracle gelieferte Lösung (siehe Abbildung 5.7) besitzt nun ebenfalls eine komplett andere Verbundreihenfolge. Zuerst wird die Selektion auf der Relation S durchgeführt, danach wird das Ergebnis daraus mit einem Rel-Index-Join mit der Relation H
zusammengeführt. Als nächstes Folgt ein Rel-Index-Verbund mit der Relation V. Als
letzter Verbund findet ein Rel-Index-Verbund mit der Relation P statt.
Die beiden Anfragebäume sind von der Struktur her gleich, Hauptunterschied ist hier die
Verwendung von Hash-Verbunden in RELOpt im Gegensatz zu Rel-Index-Verbunden in
der Lösung des Oracle-Systems.
5.3. VERGLEICHE MIT DER ORACLE-DATENBANK
Index/elim
πP.Name
39
(1)
Tree(P.Name)(5)
⋊
⋉Hash
P.ID=V.gelesenVon (5)
Hash(·)
⋊
⋉Hash
V.VorlNr=H.VorlNr (5)
Hash(·)
Hash(·)
⋊
⋉Hash
H.MatrNr=S.MatrNr (3)
V
Hash(·)
Hash(·)
Rel
σS.Semester
=’5’ (1)
H
Hash(·)
P
S
Abbildung 5.6: Beispielanfrage mit Selektion durch RELOpt optimiert
πP.Name (5)
⋊
⋉Rel-Index
P.ID=V.gelesenVon (5)
⋊
⋉Rel-Index
V.VorlNr=H.VorlNr (4)
⋊
⋉Rel-Index
H.MatrNr=S.MatrNr (3)
Rel
σS.Semester
=’5’ (2)
P ID PK
V VORLNR PK
H VORLNR MATRNR PK
S
Abbildung 5.7: Beispielanfrage mit Selektion durch Oracle optimiert
5.3.3
Beispielanfrage mit Kartesischen Produkten
Formt man die Beispielanfrage so um, dass sie Selektionen und kartesische Produkte
statt Verbunde benutzt, liefert RELOpt die gleiche Lösung wie vorher (Abbildung 5.6).
40
KAPITEL 5. EXPERIMENTE UND ANWENDUNGEN
Die Lösung des Oracle-Systems ist auch in diesem Fall unverändert (Abbildung 5.7).
Die interne Behandlung von Selektionen und kartesischen Produkten ist also in beiden
Systemen vergleichbar.
Die benutzte Anfrage:
(PROJECTION P.Name
(SELECTION (AND S.Semester=’5’
P.ID=V.gelesenVon
V.VorlNr=H.VorlNr
H.MatrNr=S.MatrNr)
(PRODUCT P (PRODUCT V (PRODUCT H S)))))
Stellt man nachfolgende Anfrage, so kann man einen deutlichen Unterschied zwischen
dem Oracle-Optimierer und RELOpt feststellen. Die Anfrage soll die Semester der Studenten liefern, die bei Professor ’D’ eine Vorlesung belegt haben.
(PROJECTION S.Semester
(SELECTION P.Name=’D’
(JOIN P.ID=V.gelesenVon P
(JOIN V.VorlNr=H.VorlNr V
(JOIN H.MatrNr=S.MatrNr H S)))))
Index/elim
πS.Semester (1)
Tree(S.Semester )(20)
⋊
⋉Rel-Index
H.MatrNr=S.MatrNr (7)
⋊
⋉Hash
V.VorlNr=H.VorlNr (6)
Hash(·)
Hash(·)
N.-Loop
⋊
⋉P.ID=V.gelesenVon (2)
Rel
σP.Name=’D’
(1)
Hash(·)
S
H
V
P
Abbildung 5.8: weitere Beispielanfrage durch RELOpt optimiert
5.3. VERGLEICHE MIT DER ORACLE-DATENBANK
41
RELOpt liefert für diese Anfrage die Lösung in Abbildung 5.8. Diese unterscheidet sich
komplett von der Lösung des Oracle-Systems in Abbildung 5.9. Ändert man die Anfrage
leicht, indem man ein NOT vor die Selektionsbedingung setzt, liefert RELOpt immer noch
die gleiche Lösung. Die Lösung des Oracle-Systems ist in Abbildung 5.10 zu finden. Diese
ist wieder der von RELOpt gelieferten Lösung weitestgehend identisch.
πP.Name (7)
⋊
⋉Rel-Index
H.MatrNr=S.MatrNr (7)
⋊
⋉Hash
(P.ID=V.gelesenVon)∧(V.VorlNr=H.VorlNr) (6)
Merge
⋊
⋉true
(3)
Rel
σP.Name=’D’
(2)
P
S MATRNR PK
V
Sort(·)
H VORLNR MATRNR PK
Abbildung 5.9: weitere Beispielanfrage durch Oracle optimiert
πS.Semester (10)
⋊
⋉Hash
H.MatrNr=S.MatrNr (10)
⋊
⋉Hash
V.VorlNr=H.VorlNr (7)
⋊
⋉Hash
P.ID=V.gelesenVon (5)
Rel
σP.Name=’D’
(2)
H VORLNR MATRNR PK
Hash(·)
S
V
P
Abbildung 5.10: die Beispielanfrage mit NOT durch Oracle optimiert
42
5.3.4
KAPITEL 5. EXPERIMENTE UND ANWENDUNGEN
Fazit
Bei den getesteten Anfragen sind sich die Lösungen von RELOpt und die des OracleSystems sehr ähnlich. Bei dem letzten Beispiel allerdings sieht man eine Eigenschaft des
Oracle-Optimierers, bei einelementigen Ergebnismengen aus einer Selektion eine komplett andere Lösung zu liefern. Im Beispiel liefert die Selektion nur ein einziges Tupel.
Das nachfolgende kartesische Produkt mit der größten Relation H ist daher sehr kostengünstig zu berechnen. Danach folgt ein Hash-Verbund mit zwei Bedingungen.
Verbunde mit mehreren Bedingungen sind in RELOpts Optimierungsstrategie nicht vorgesehen. Hier sollte noch genauer untersucht werden, wieviel Kosten wirklich durch diese
Art der Optimierung gespart werden können.
Kapitel 6
Erweiterungen am Programm
RELOpt
In diesem Kapitel folgen detaillierte Beschreibungen der durchgeführten Änderungen
und Erweiterungen am Programm RELOpt. Um den kompletten Entwicklungsgang des
Programms zu betrachten, sollten auch die vorhergehenden Arbeiten von [Mak03] und
[War03] beachtet werden. Zuerst folgt ein kurzer Abriss über die durchgeführten Arbeiten, danach dann die Implementierung.
6.1
Regeln
Die in Kapitel 2 definierten Regeln wurden umgesetzt. Hierzu wurde ein vereinheitlichtes Regelsystem eingeführt, damit sowohl algebraische als auch physische Regeln eine
gemeinsame Schnittstelle haben. Dies vereinfacht die Handhabung der Regeln. Denkbar
wären dann auch gemischte Abarbeitung algebraischer und physischer Regeln.
Weiterhin wurde eine Gruppierungsschnittstelle definiert. Diese ermöglicht es, Regeln
in Gruppen zusammenzufassen. Der algebraische und der physische Optimierer wurden
so erweitert, dass sie die neuen Regelstrukturen unterstützen. Eine Regelgruppe kann
Regeln und weitere Regelgruppen enthalten.
Beide Optimierer unterstützen nun auch iterative Regelbearbeitung. Hierbei werden Regeln in Gruppen zusammengefasst, und diese Regelgruppe wird dann vom Optimierer
so lange angewendet, bis sich keine Änderungen mehr im Anfragebaum ergeben.
Zum Beispiel: (Gruppe A (Gruppe B)* Gruppe C)*
Hier wird zuerst Gruppe A bearbeitet, danach solange Gruppe B, bis keine Veränderung
mehr eintritt, und danach Gruppe C. Anschließend beginnt die Abarbeitung wieder von
vorn, solange wie sich noch etwas im Anfragebaum ändert.
43
44
6.2
KAPITEL 6. ERWEITERUNGEN AM PROGRAMM RELOPT
Regelauswahl
In einem ersten Schritt wurden die beiden unterschiedlichen Regelauswahlfenster jeweils
durch ein neues ersetzt. Das neue Fenster ist so konzipiert, dass es sowohl die algebraischen als auch die physischen Regeln verwalten kann. Dies wurde durch die in Abschnitt
6.1 erwähnte Schnittstelle möglich. Die Schnittstelle wird zu einem späteren Zeitpunkt
definiert. Auch die Gruppierungsfunktion wurde umgesetzt. Regelgruppen lassen sich
nun über die grafische Benutzerschnittstelle anlegen und löschen.
Das neue Fenster findet sich unter Abbildung 6.1. In diesem Fenster sieht man übersichtlich alle Regeln des jeweiligen Optimierers aufgelistet. Regelgruppen sind wie in einem
Dateisystem angeordnet. Die Inhalte einer Regelgruppe können per Doppelklick ein- und
ausgeblendet werden. In der rechten Spalte befindet sich ein Auswahlknopf. Dieser dient
dazu, die Iteration für das jeweilige Element zu aktivieren, bzw. zu deaktivieren.
Abbildung 6.1: Dialog für die Verwaltung physischer Regeln und Gruppen
Ein Klick auf den Knopf Gruppe hinzufügen öffnet einen neuen Dialog (siehe Abbildung
6.2). In diesem Dialog kann man den Gruppennamen festlegen. Ein Klick auf OK legt
die neue Gruppe an. Abbrechen schließt den Dialog, ohne eine neue Gruppe anzulegen.
In der Tabelle kann man durch Doppelklick auf die Beschreibung in einen Editiermodus
gelangen, um die Beschreibung zu ändern. Man kann eine beliebige Anzahl Regeln in
der neuen Gruppe erstellen, oder Regeln aus anderen Gruppen in die neue Gruppe
verschieben.
Die anderen Knöpfe haben die in [War03] eingeführten Funktionen.
6.3. ZUSAMMENLEGUNG VON RELATION UND METADATEN
45
Abbildung 6.2: Dialog für das Anlegen von neuen Gruppen
6.3
Zusammenlegung von Relation und Metadaten
Die in den vorhergehenden Versionen getrennte Bearbeitung von Relationen und Me”
tadaten“ wurde in dieser Version aufgehoben, da die Beschreibung der Relationen auch
zu den Metadaten zählt. Der Knopf Relationen wurde entfernt. Unter dem Knopf Metadaten (siehe Abbildung 4.1) finden sich nun beide Dialog-Tabellen (siehe Abb. 6.3).
Die Statistischen Daten können nun direkt in der Tabelle geändert werden, ohne den
Umweg über den Ändern-Dialog. Dieser wird noch für das Setzen und Löschen von
Indexen und Sortierungen benötigt. Außerdem wird er für die Änderung der Anzahl der
eindeutigen Tupel benötigt.
Abbildung 6.3: Der neue Metadaten-Dialog
46
KAPITEL 6. ERWEITERUNGEN AM PROGRAMM RELOPT
6.4
Die Paketstruktur
Es folgt ein kurzer Überblick über die Struktur des Programms (siehe Abbildung 6.4).
de.unihannover.dbs.sopt
gui
test
struc
sun
rules
search
tree
alg
phys
sqlp
db.oracle
rules
rules
rules
Abbildung 6.4: Die Paketstruktur von RELOpt
Das Paket gui enthält alle Klassen (d.h. Dialoge und Masken) der grafischen Benutzerschnittstelle. Im Paket db.oracle findet man die Anbindung an die Oracle Datenbank.
Im Paket test liegt die Hauptklasse zum Ausführen des Programms.
Das Paket sqlp enthält den Anfrageübersetzer. Das Paket tree enthält die Implementierung zur Visualisierung der einzelnen Schritte als Baumdiagramme.
Alle für die Optimierung benötigten Klassen finden sich im Paket struc. In rules liegen
Superklassen und Interfaces für die Anordnung und Speicherung der Regeln in der neuen
Baumstruktur.
Die Klassen zur algebraischen Optimierung sind in alg zu finden. Die Klassen für die
physische Optimierung befinden sich in phys. In search findet man Algorithmen für die
kostenbasierte Optimierung.
6.5. IMPLEMENTIERUNG
6.5
6.5.1
47
Implementierung
Vereinheitlichung des Regelsystems
Im Hinblick auf spätere Erweiterbarkeit wurde das gesamte Regelsystem vereinheitlicht. Alle algebraischen und physischen Regeln haben nun eine gemeinsame Oberklasse
AbstractRule. Diese befindet sich im Paket sopt.struc.rules.
<<interface>>
RuleNode
DIRECTION_LEFT_TO_RIGHT
DIRECTION_RIGHT_TO_LEFT
+getName()
+getDirection()
+getDescription()
+isBidirectional()
+setDirection(boolean)
+toString()
SortedDup
Projection
Rule
IndexDup
Projection
Rule
AbstractRule
physRule
+applyRule(Relation)
NestedDup
Projection
Rule
Merge
Join
Rule
IndexIndex
Join
Rule
RelIndex
Join
Rule
NestedLoop
Join
Rule
Merge
Semijoin
Rule
IndexIndex
Semijoin
Rule
RelIndex
Semijoin
Rule
NestedLoop
Semijoin
Rule
Merge
Antisemijoin
Rule
Merge
Union
Rule
Rel
Selection
Rule
Product
Rule
RelIndex
Antisemijoin
Rule
IndexIndex
Union
Rule
IndexIndex
Antisemijoin
Rule
RelIndex
Union
Rule
NestedLoop
Antisemijoin
Rule
NestedLoop
Union
Rule
Index
Selection
Rule
Intersection
Rule
Difference
Rule
Abbildung 6.5: Klassendiagramm de.unihannover.dbs.sopt.phys.rules
48
KAPITEL 6. ERWEITERUNGEN AM PROGRAMM RELOPT
Die aus dem statischen Optimierer1 extrahierten physischen Regeln (siehe Kapitel 2)
sind in dem neuen Packet struc.phys.rules zu finden (siehe Abbildung 6.5).
Die Regeln ProductRule, DifferenceRule und IntersectionRule unterscheiden sich
von den anderen Regeln, da sie den physischen Optimierer in der alten Implementierung
rekursiv aufrufen. Dies wurde so gelöst, das die Regeln die zu optimierende Relation
aufbauen, und dann mit einer Nachricht an den laufenden Optimierer senden. Dieser
kann dann die Nachricht empfangen, die neue Relation daraus extrahieren und neu
bearbeiten.
6.5.2
Umsetzung der neuen Regelstruktur
Um die Organisation der Regeln in Gruppen möglichst effizient durchzuführen, wurde
von der bisher verwendeten Speicherung in Listen abgewichen. Die Regeln werden nun
in einer baumähnlichen Struktur gespeichert, die im folgenden beschrieben wird:
• RuleNode
Diese Klasse ist ein Interface. Alle Knoten im neuen Regelbaum müssen dieses
implementieren. Es stellt Methoden zur Identifizierung der Regel (z.B. Name und
Beschreibung) zur Verfügung.
– getName
Liefert den Namen des Knotens
– getDirection
Liefert die Richtung des Regelknotens.
– getDescription
Liefert die Beschreibung de Knotens.
– isBidirektional
Liefert wahr, wenn die Regel Bidirektional ist.
– setDirection
Setzt die Ausführungsrichtung der Regel.
– toString
Liefert eine Stringdarstellung der Regel.
• RuleGroupNode
Diese Klasse repräsentiert innere Knoten, also die Regelgruppen. Diese können vom
Benutzer angelegt werden. Sie enthalten einen Namen, dazu noch Regeln und/oder
weitere Gruppen. Sie stellt Methoden zum Zugriff auf die enthaltenen Regeln und
Gruppen zur Verfügung. Sie implementiert das Interface RuleNode.
1
siehe [Mak03] und [War03]
6.5. IMPLEMENTIERUNG
49
– getChildren
Liefert die in der Gruppe enthaltenen Regeln/Gruppen.
– add
Fügt eine Regel oder Gruppe hinzu.
– size
Liefert die Anzahl der Regeln. (Sind z.B. 10 Regeln in 3 Gruppen liefert size()
10, nicht 13)
– isEmpty
Liefert wahr wenn der Knoten keine Kinder hat.
– setTo
Setzt diesen Knoten gleich dem übergebenen. Beide zeigen dann auf den selben Baum. Name und Beschreibung sind identisch.
– setName
Setzt den Namen der Gruppe.
– setDescription
Setzt die Beschreibung der Gruppe.
– isIterative
Liefert wahr, wenn die Gruppe iterativ ist.
– setRecursive
Setzt ob die Gruppe rekursiv ist.
• AbstractRule
Diese Klasse ist die neue Oberklasse aller algebraischen und physischen Regeln. Sie
enthält Methoden zum Setzen und Auslesen der Ausführungsrichtung der Regel.
Außerdem noch Methoden, die den Namen und die Beschreibung der Regel liefern.
Klassen, die AbstractRule implementieren, müssen einen String DESCRIPTION
als globale Variable haben, da dieser von der Methode getDescription mit Hilfe
von Java-Reflection ausgelesen wird.
Die Klasse implementiert das Interface RuleNode.
• RuleFactory
Diese Klasse stellt eine Methode zum Instanziieren von Regeln zur Verfügung. Man
übergibt ihr den Namen der Regel und bekommt eine neue Instanz dieser Regel
geliefert. Sie wird von den Auswahldialogen benutzt, um neue Regeln einzufügen.
– constructRule
Liefert die zum übergebenen String passende Regel. Ein Aufruf mit ARule“
”
würde also eine Instanz der Klasse ARule liefern.
Im folgenden Klassendiagramm (Abbildung 6.6) ist die wichtigste Neuerung die Klasse
AbstractRule und das Interface RuleNode. Beide sind Teil der eingeführten Vereinheitlichung der Regelstruktur.(siehe 6.5.1)
50
KAPITEL 6. ERWEITERUNGEN AM PROGRAMM RELOPT
<<interface>>
Rule
<<interface>>
MetadataBasedRule
+optimize(AlgebraicTree)
AlgRule
+optimizeBottomUp(Relation)
+optimizeTopDown(Relation)
+optimize(Relation)
+optimizw(Relation,boolean)
ARule
...
ERule
FRule
+setMetadata(Metadata)
<<interface>>
RuleNode
DIRECTION_LEFT_TO_RIGHT
DIRECTION_RIGHT_TO_LEFT
+getName()
+getDirection()
+getDescription()
+isBidirectional()
+setDirection(boolean)
+toString()
AbstractRule
GRule
HRule
IRule
...
ZRule
Abbildung 6.6: Klassendiagramm de.unihannover.dbs.sopt.alg.rules
6.5.3
Anpassung des physischen Optimierers
Um aus dem vorhandenen starren physischen Optimierer2 einen flexiblen regelbasierten
Optimierer zu machen, benötigt man eine gemeinsame Schnittstelle (siehe Kap. 6.5.2)
der neuen Regeln. Der Optimierer wurde nun so erweitert, das er durch die neue Datenstruktur laufen kann. Sollte er dabei auf iterative Regeln oder Gruppen stoßen, so
wendet er diese so lange an, bis keine Änderungen mehr im Anfragebaum auftreten.
6.5.4
Die Regelauswahl
Die Benutzerschnittstelle wurde um eine regelbasierte Auswahl bei der physischen Optimierung ergänzt. Dort kann der Benutzer die unter Abschnitt 2 zu findenden Regeln
in einer Tabelle anordnen, laden und speichern. Hierzu wurde die schon in [War03] eingeführte regelbasierte Auswahl des Algebraischen Optimierers refaktorisiert und an die
neue Regelstruktur angepasst(siehe 6.5.2).
2
die Klasse AttrTransformer
6.5. IMPLEMENTIERUNG
51
Die Auswahldialoge für algebraische und physische Regeln wurden von JTable auf
JTreeTable umgestellt. Durch die Verwendung einer Tabelle, die die Daten aus einer
Baumstruktur darstellt, kann man die Regeln in Gruppen unterteilen, Gruppen von
Regelgruppen bilden und diese übersichtlich darstellen. Diese Funktionalität wurde im
Hinblick auf die spätere Zentralisierung der Regelauswahl (siehe Kap. 7) bereits jetzt
eingeführt. Die vorher verwendeten Listen zur Verwaltung der Regeln wurden durch
eine Baumstruktur ersetzt, diese wird in Abschnitt 6.5.2 erläutert.
6.5.5
Der Join-Order-Algorithmus
Die Implementierung des Join-Order-Algorithmus aus Kapitel 3 besteht aus drei Klassen:
• JOTableEntry
Diese Klasse repräsentiert eine Zeile der Optimierungstabelle. Sie enthält die folgenden Methoden:
– getCardinality
Liefert die Kardinalität des Eintrags.
– getProductCardinality
Liefert die Kardinalität des Eintrags ohne Berücksichtigung der Selektivität.
– setCardinality
Setzt die Kardinalität des Eintrags.
– getPages
Liefert die Anzahl der belegten Seiten.
– getProductPages
Liefert die Anzahl der belegten Seiten ohne Berücksichtigung der Selektivität.
– setPages
Setzt die Anzahl der belegten Seiten.
– getCost
Liefert die Kosten.
– setCost
Setzt die Kosten.
– getLHS
Liefert die Startmenge.
– setLHS
Setzt die Startmenge.
– getSet
Liefert die Menge der beteiligten Relationen.
52
KAPITEL 6. ERWEITERUNGEN AM PROGRAMM RELOPT
– setSet
Setzt die Menge der beteiligten Relationen.
– addToSet
Fügt die übergebene Relation der Menge hinzu.
– addToLHS
Fügt die übergebene Relation der Startmenge hinzu.
– getFanSel
Liefert die Selektivität.
– setFanSel
Setzt die Selektivität.
– toString
Liefert eine Darstellung des Eintrags als String.
– equals
Liefert wahr, wenn der übergebene Tabelleneintrag identisch zu diesem ist.
– clone
Liefert eine exakte Kopie des Eintrags.
– compareTo
Liefert das Ergebnis des Vergleichs der beiden Stringrepräsentationen, wenn
die Menge der Relationen gleich lang ist. Sollte die Menge der Relationen verschieden sein, so wird die Anzahl der Elemente in der ersten Menge minus der
Anzahl der Elemente in der zweiten Menge zurückgegeben. So ist garantiert,
das Einträge mit kurzen Mengen vor Einträgen mit langen Mengen kommen,
und Einträge mit gleichlangen Mengen alphabetisch sortiert sind.
• JOTable
Diese Klasse repräsentiert die Optimierungstabelle. Sie implementiert TableModel,
sowie die folgende Methoden:
– add
Fügt einen neuen Tabelleneintrag hinzu. Sollte der übergebene Eintrag schon
vorhanden sein, so wird er nicht eingefügt.
– get
Liefert den Eintrag, der in der übergebenen Zeile steht.
– getLeastCostItemForSet
Liefert die Startmenge für die übergebene Menge.
– getItemForSet
Liefert den Eintrag, dessen Relationenmenge identisch mit der übergebenen
Menge ist.
– getItemForArray
Liefert den Eintrag, dessen Inhalt der Relationenmenge identisch mit dem
Inhalt des übergebenen Arrays ist.
6.5. IMPLEMENTIERUNG
53
• JORule
Diese Klasse repräsentiert die Join-Order-Optimierung als algebraische Optimierungsregel. Sie erweitert AlgRule und implementiert MetadataBasedRule3 . Weiterhin hat sie folgende Methoden:
– optimize
Optimiert den übergebenen AlgebraicTree. Zuerst wird der Anfang des Teilbaums gesucht, der die Verbunde enthält. Dieser wird mit Hilfe des JoinOrder-Algorithmus optimiert. Das optimierte Ergebnis wird anstelle des alten
Teilbaums in den Anfragebaum eingefügt.
– setMetadata
Setzt die Metadaten auf die übergebenen Metadaten.
– getTable
Liefert die Optimierungstabelle.
– getResult
Liefert das Ergebnis als String.
3
siehe [War03]
54
KAPITEL 6. ERWEITERUNGEN AM PROGRAMM RELOPT
Kapitel 7
Ausblick
• Erweiterung des Sprachumfangs
Da die in RELOpt implementierten Konstrukte noch nicht die komplette Relationenalgebra abdecken, wären hier einige Ergänzungen notwendig. Als Beispiel sei
hier der Outer-Join genannt. Auch eine Unterstützung der erweiterten Relationenalgebra, wie zum Beispiel Aggregation und Gruppierung, wäre sinnvoll.
• Einlesen des Oracle-Anfrageplans
Die Schnittstelle zum Oracle-System sollte so erweitert werden, dass die von Oracle
gelieferten Ergebnisse in die von RELOpt verwendete Baumstruktur eingelesen
werden. Dies würde auch die Visualisierung der gelieferten Anfragepläne ermöglichen.
• Erweiterung des Join-Order-Algorithmus
Der Join-Order-Algorithmus sollte so erweitert werden, dass Pipeline-günstige Bäume als Ergebnis geliefert werden, wenn die erwarteten Gesamtkosten mit Pipelines
geringer sind als die Lösung ohne Pipelinebetrachtung.
Da Pipelines Teil der physischen Optimierung sind, würde sich hier eine Erweiterung von RELOpt um parallele Betrachtung alternativer Lösungen anbieten. Der
Join-Order-Algorithmus würde dann einmal die berechnete optimale“ Lösung lie”
fern, parallel dazu aber auch eine Lösung, die eine möglichst lange Pipeline erlaubt.
In den nachfolgenden Schritten wäre ein direkter Vergleich der beiden Lösungen
möglich, um am Ende die optimale auszuwählen.
• Späte Duplikateneliminierung
Da zum jetzigen Zeitpunkt alle Projektionen mit Duplikateneliminierung implementiert sind, wäre hier eine Erweiterung von RELOpt um physische Regeln für
Projektionen ohne Duplikateneliminierung sinnvoll. Der Optimierer hätte dann die
Möglichkeit, kostspielige Duplikateneliminierung erst beim Endergebnis durchzuführen.
55
56
KAPITEL 7. AUSBLICK
• Anpassung der Regeln an iterative Abarbeitung
Um die in dieser Arbeit eingeführte iterative Abarbeitung von Regelgruppen komplett nutzen zu können, müssten alle Regeln so angepasst werden, dass sie nicht
mehr selbsttätig durch den Anfragebaum laufen, sondern nur noch den übergebenen Teilbaum optimieren und sich dann beenden. Das Durchlaufen des Anfragebaums wird nun Aufgabe des Optimierers. Durch diese Änderung ist eine bessere
Kontrolle gegeben, wann und wo welche Regeln in welcher Reihenfolge ausgeführt
werden.
• Manuelle Ersetzung von Operationen
Um die Arbeit mit RELOpt zu verbessern, sollte ein Experimentierbereich implementiert werden, in dem der Benutzer mit der vom RELOpt gelieferten Anfrage
verschiedene Operationen testen kann. Hier sollte es möglich sein, die einzelnen
Operationen durch andere ersetzen zu können (zum Beispiel einen Merge-Verbund
durch einen Nested-Loop-Verbund) und neue Operationen in den Anfragebaum
einfügen zu können (zum Beispiel Sortierungen). Außerdem sollte der Benutzer
die Möglichkeit haben, Operationen im Anfragebaum zu verschieben. In der Kostenanzeige sollten immer die aktuellen Kosten angezeigt werden, so dass man
direkt die Auswirkungen sehen kann.
Abbildungsverzeichnis
1.1
Anfragebaum der Beispielanfrage . . . . . . . . . . . . . . . . . . . . . .
3
1.2
algebraischer Baum der Beispielanfrage . . . . . . . . . . . . . . . . . . .
4
1.3
physischer Baum der Beispielanfrage . . . . . . . . . . . . . . . . . . . .
4
1.4
Anfragebaum des Beispiels nach der kostenbasierten Optimierung . . . .
5
4.1
Die Knöpfe im Hauptfenster von RELOpt . . . . . . . . . . . . . . . . .
21
4.2
Dialog für die Bearbeitung von Tabellen . . . . . . . . . . . . . . . . . .
22
4.3
Dialog für den Datenbanklogin . . . . . . . . . . . . . . . . . . . . . . . .
22
4.4
Dialog für den Import von Tabellen . . . . . . . . . . . . . . . . . . . . .
23
4.5
Oracle Anfrageplan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26
4.6
Ausschnitt aus dem Paket sopt.sqlp.rules . . . . . . . . . . . . . . . . . .
30
4.7
Beispielanfragebaum für den SQL-Übersetzer . . . . . . . . . . . . . . . .
31
4.8
Beispielanfrage in SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . .
31
4.9
Dialog für den Anfrageplan Vergleich . . . . . . . . . . . . . . . . . . . .
32
5.1
Anfragebaum der Beispielanfrage (JOA/MSA) . . . . . . . . . . . . . . .
34
5.2
Anfragebaum der Beispielanfrage mit verschobener Selektion . . . . . . .
34
5.3
Anfragebaum des Beispiels aus Kapitel 1 . . . . . . . . . . . . . . . . . .
35
5.4
Beispielanfrage durch RELOpt optimiert . . . . . . . . . . . . . . . . . .
37
57
58
ABBILDUNGSVERZEICHNIS
5.5
Beispielanfrage durch Oracle optimiert . . . . . . . . . . . . . . . . . . .
38
5.6
Beispielanfrage mit Selektion durch RELOpt optimiert . . . . . . . . . .
39
5.7
Beispielanfrage mit Selektion durch Oracle optimiert . . . . . . . . . . .
39
5.8
weitere Beispielanfrage durch RELOpt optimiert . . . . . . . . . . . . . .
40
5.9
weitere Beispielanfrage durch Oracle optimiert . . . . . . . . . . . . . . .
41
5.10 die Beispielanfrage mit NOT durch Oracle optimiert . . . . . . . . . . . .
41
6.1
Dialog für die Verwaltung physischer Regeln und Gruppen . . . . . . . .
44
6.2
Dialog für das Anlegen von neuen Gruppen . . . . . . . . . . . . . . . . .
45
6.3
Der neue Metadaten-Dialog . . . . . . . . . . . . . . . . . . . . . . . . .
45
6.4
Die Paketstruktur von RELOpt . . . . . . . . . . . . . . . . . . . . . . .
46
6.5
Klassendiagramm de.unihannover.dbs.sopt.phys.rules . . . . . . . . . . .
47
6.6
Klassendiagramm de.unihannover.dbs.sopt.alg.rules . . . . . . . . . . . .
50
Tabellenverzeichnis
1.1
Beispielrelationen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2
1.2
Indexe der Beispielrelationen . . . . . . . . . . . . . . . . . . . . . . . . .
3
3.1
Die Basisrelationen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
3.2
Tabelle nach der Initialisierung . . . . . . . . . . . . . . . . . . . . . . .
15
3.3
Tabelle für die Beispielanfrage V × P × S × H . . . . . . . . . . . . . . .
17
3.4
Neue Tabelle für die Beispielanfrage V × P × S × H
. . . . . . . . . . .
19
3.5
Erweiterte Basisrelationen . . . . . . . . . . . . . . . . . . . . . . . . . .
19
3.6
Tabelle für die Beispielanfrage V o
n (H o
n S) . . . . . . . . . . . . . . . .
20
3.7
Optimierungstabelle für die Beispielanfrage aus Kapitel 1 . . . . . . . . .
20
5.1
Oracle-Operationen und ihre Umsetzung in RELOpt . . . . . . . . . . .
36
59
60
TABELLENVERZEICHNIS
Literaturverzeichnis
[Lip03] U. Lipeck. Vorlesungsskript Datenbanksysteme I, Wintersemester 2003/2004.
2003. URL:http://www.dbs.uni-hannover.de/lehre/dbs0304/.
[Mak03] M. E. Makoui: Heuristische Anfrageoptimierungen in Relationalen Datenbanken. Diplomarbeit, Institut für Informationssysteme, Universität Hannover,
2003.
[Mit95] B. Mitschang: Anfrageverarbeitung in Datenbanksystemen. Vieweg, Braunschweig/Wiesbaden, 1995.
[ORA]
Oracle Database 10g Release 1 (10.1) Documentation. Oracle Corporation.
URL:http://www.oracle.com/technology/documentation/database10g.html.
[VM96] B. Vance, D. Maier: Rapid Bushy Join-order Optimization with Cartesian
Products. In H. V. Jagadish, I. S. Mumick (eds.), Proceedings of the 1996
ACM SIGMOD International Conference on Management of Data, Montreal,
Quebec, Canada, June 4-6, 1996, ACM Press, 1996, 35–46.
[War03] H. Warneke: Erweiterung eines Simulators für relationale Anfrageoptimierungen. Bachelorarbeit, Institut für Informationssysteme, Universität Hannover,
2003.
61
Herunterladen