Zur Anfragebearbeitung gehört bei jeder Datenbank ein Optimizer. Der Optimizer versucht für eine Anfrage den optimalen Ausführungsplan zu ermitteln. Der Plan beschreibt u.a in welcher Reihenfolge Tabellen zu lesen sind und welche Indizes zu benutzen sind. Der MaxDB Optimizer arbeitet kostenbasiert. Das heißt, er versucht für jede mögliche Zugriffsstrategie zu ermitteln wie hoch die “Kosten” für die Ausführung sind. Das Kostenmodell von MaxDB beruht wesentlich auf der Anzahl von I/O-Zugriffen.
Bei Anfragen, die nur eine Tabelle betreffen, ermittelt MaxDB (und MySQL) statistische Informationen über Tabellen und Indizes per Online-Evaluation. MaxDB testet wie selektiv ein Zugriff wäre und schätzt die benötigte Anzahl von I/O-Zugriffen. Bei Anfragen, die mehrere Tabellen betreffen wird die Online-Evaluation, die immer aktuelle Werte liefert, als zu langsam angesehen. Deshalb werden zuvor berechnete Tabellen- und Indexstatistiken herangezogen. Wenn diese nicht vorliegen, dann muß geschätzt werden. Wenn sie veraltet sind und keine Korrelation zur realen Datenlage aufweisen, führt dies zur Auswahl von Plänen, die nicht optimal sind. In beiden Fällen müssen die Statistiken neu berechnet und aktualisiert werden. Doch wie erfährt man davon? Seit MaxDB 7.6.00 ist die Antwort einfach: MaxDB meldet sich automatisch!
In Version 7.6.00 von MaxDB wurde ein neues DBM-Kommando “auto_update_statistics” eingeführt, welches dazu benutzt werden kann die Optimizer Statistiken automatisch aktualisieren zu lassen. Wird das Feature mit dem Kommando auto_update_statistics ON
aktiviert. auto_update_statistics SHOW
zeigt an, ob die Funktion aktiviert ist oder nicht und auto_update_statistics OFF
deaktiviert die Funktion.
./dbmcli on BW>auto_update_statistics SHOW
OK
OFF
---
./dbmcli on BW>auto_update_statistics ON
OK
---
Die Aktivierung startet implizit einen Event Task (siehe auch Eventing mit MaxDB), der aktiviert wird sobald MaxDB erkennt, daß Optimizer Statistiken fehlen oder nicht mehr aktuell sind. Achtung, die implizit gestartete Event Task wird bei der Prüfung der maximal erlaubten Event Tasks mitgezählt. Die maximale Anzahl von Event Tasks wird durch den Datenbankparameter _MAXEVENTTASKS
bestimmt.
Wie wird die Notwendigkeit zur Aktualisierung von Statistiken erkannt?
Prinzipiell sehe ich zwei Ansätze, um zu erkennen, daß Statitiken veraltern. Die erste Variante besteht in der Ãœberwachung von Änderungsoperationen und der Neuanlage von Datenbankobjekten. Die zweite Variante ist besteht darin, mit Informationen zu arbeiten, die während der Anfrageabarbeitung ohne Zusatzaufwand anfallen. Dies ist der von MaxDB eingeschlagene Weg.
Zwei Informationen stehen quasi kostenlos zur Verfügung. Bei der Bearbeitung eines Joins muß geprüft werden, ob überhaupt Spaltenstatistiken zur Verfügung stehen. Fehlen diese, wird die Erstellung der Statistiken gefordert. Während der Anfragebearbeitung steht oft noch eine zweite Information zur Verfügung: die Tabellengröße. Wenn die gemessene Tabellengröße einer Tabelle, die mindestens 200 Datenseiten (a 8kB – default) groß ist, um mindestens 20% vom gespeicherten Wert abweicht, dann wird eine Aktualisierung der Statistiken angefordert. Weil die Granularität der MaxDB Statistiken relativ grob ist, sind diese zwei Informationen in den allermeisten Fällen ausreichend um die Notwendigkeit zur Aktualisierung der Statistiken zu erkennen.
Ich kann mir lediglich eine Lücke denken: massive Änderungen an der Anzahl von unterschiedlichen Werten in einem Index, der während eines Join verwendet wird. Doch dies ist ein allgemeines Problem, welches sich nicht auf die Aktualisierung der Statistiken beschränkt.
Wird die Notwendigkeit zur Aktualisierung erkann, dann erfolgt zunächst ein Eintrag in der Systemtabelle SYSUPDSTATWANTED
. Die Tabelle hat vier Spalten: SCHEMANAME, OWNER, TABLENAME, COLUMNNAME
. MaxDB hinterlegt in SYSUPDSTATWANTED
welche Spalte (COLUMNNAME
) in welcher Tabelle (SCHEMANAME, OWNER, TABLENAME
) eine Aktualisierung der Statistiken benötigt. Einmal gespeichert, können die Informationen aus der Tabelle ausgelesen werden und die Statistiken selektiv aktualisiert werden.
Fazit
Hatte man bislang in MaxDB nur die Option selbständig die Optimizerstatistiken in regelmäßigen Abständen zu überwachen oder gar die Ãœberwachung auszulassen und erst bei einer Verlangsamung der Abfragebearbeitung zu reagieren, so macht MaxDB das Leben des Datenbankadministrators wieder ein Stückchen einfacher. Die erste Implementierung ist geeignet, um das Gros der Fälle zu erkennen in denen die Optimizerstatistiken aktualisiert werden müssen. Die manuelle Ãœberwachung kann also seltener erfolgen oder ganz eingespart werden.
Nachtrag vom 13.10.2005: Stichprobengröße
Es ging mir durch den Kopf als ich den Blogeintrag schrieb. Aber ich wußte die Antwort nicht: welche Stichprobengröße verwendet MaxDB, wenn Statistiken erstmals automatisch berechnet werden? Dabei hätte ich es mir denken können, schließlich habe ich das Handbuch gelesen…
MaxDB betrachtet bei der Erstellung von Statistiken nur so viele Einträge aus einer Tabelle, wie es der Administrator konfiguriert hat. Konfiguriert wird der Wert mit CREATE TABLE
bzw. ALTER TABLE
. Die Stichprobengröße wird in Prozent oder als absoluter Wert angegeben:
. Soweit kannte ich das Spielchen.
Doch welche Größe wird bei der automatischen Aktualisierung der Statistiken für eine neue Tabelle verwendet? Die Antwort enttäuschte mich etwas. Es gibt keine Änderung an der bisherigen Regel, nach wie vor wird eine absolute Anzahl von 20.000 Zeilen verwendet: “If a SAMPLE definition is not defined, the database system uses the value 20000 ROWS.” . Wenn eine neue Tabelle sich in der Größenordnung von >= 1 Million Zeilen bewegt, dann ist diese Stichprobengröße in der Regel nicht ausreichend. Die Entscheidung der MaxDB-Entwickler die Größe einer neuen Tabelle nicht in die Stichprobengröße einfließen zu lassen ist einerseits verständlich, um die Systembelastung nicht ungewollt ausufern zu lassen, andererseits ist der Administrator aufgerufen hier manuell zu kontrollieren. Das wiederum geht sehr einfach, indem die Systemtabelle DOMAIN.TABLES
(Spalten: SAMPLE_ROWS, SAMPLE_SIZE
) untersucht wird, um Diskrepanzen zwischen Tabellengröße und Stichprobengröße ggf. manuell auszugleichen.