News
DBA-Tipp: Pending statistics – Glaube keiner Statistik, die du nicht selbst ge...prüft hast

Die Information ist ein schnelllebiges Gut. Jeden Tag werden wir mit hunderten Informationen zugemüllt. Deshalb sind wir bestrebt uns auf das Wesentliche zu konzentrieren und nur substantiell nachhaltige Informationen bereitzustellen.

Icon Unternehmen

Wenngleich der Oracle Optimizer an sich eine sehr ausgereifte und zuverlässige Komponente ist, kommt er ohne aktuelle und aussagefähige Statistiken nur schwer zu guten Ergebnissen. Die Enterprise Edition verfügt zur Unterstützung des Optimizers über mächtige Werkzeuge, wie etwa SQL Baselines oder SQL Profiles. In der Standard Edition hingegen ist man auf Statistiken und Histogramme beschränkt, um die Datenverteilung möglichst repräsentativ zu beschreiben und den Optimizer so zu guten Schätzungen zu führen. Entsprechend wichtig kann es, insbesondere in Produktivumgebungen, sein, Änderungen an Statistiken oder Histogrammen nicht sofort wirksam werden zu lassen, sondern vorab zu verifizieren. Für diesen Zweck eignet sich das Konzept der pending statistics, das in diesem DBA-Tipp kurz vorgestellt werden soll.

Wir greifen hierzu zurück auf das HR-Schema aus den Oracle Samples und widmen uns der Frage, welche Angestellten „Steven King“ als Manager haben. Der Optimizer schlägt bei fehlenden Statistiken folgenden Ausführungsplan vor:

Abb.: global stats

 Im Step 2 soll die EMPLOYEES-Tabelle per Full Table Scan (FTS) durchsucht werden, um den Manager mit Namen „Steven King“ zu finden. Das wäre bedingt durch den FTS zum einen sehr I/O-lastig. Zum anderen erwartet der Optimizer hierbei auch nur einen Treffer. Der Name ist also sehr selektiv, ein Index demnach angeraten. In dem Wissen, dass es auf Tabelle EMPLOYEES bereits einen Index EMP_NAME_IX(LAST_NAME, FIRST_NAME) gibt, sollten wir annehmen, dass bei Vorliegen aktueller Statistiken dieser zur Ermittlung des angefragten Managers auch genutzt würde. Das wollen wir in einer zweiten Sitzung verifizieren, ohne die Statistiken sofort global verfügbar zu machen. Dazu müssen wir zwei Dinge vorbereiten, nämlich die Nutzung von pending statistics für die Session erlauben (optimizer_use_pending_statistics=true) und die Tabelle EMPLOYEES dahingehend markieren, dass ihre Statistiken nicht sofort publiziert werden (set_table_prefs). Anschließend rechnen wir für diese Tabelle Statistiken mit den vorliegenden Standardeinstellungen (gather_table_stats):

Abb.: pending stats

In dieser Session sieht der Ausführungsplan, basierend auf aktuellen Statistiken, nun wesentlich plausibler aus. Unter anderem erfolgt die Ermittlung des Managers „Steven King“ nun, wie erwartet, über den Index EMP_NAME_IX (Step 4):

Abb.: pending stats

In der ursprünglichen Sitzung (und allen restlichen natürlich auch) sind diese Statistiken allerdings noch nicht bekannt. Hier wird nach wie vor der alte Ausführungsplan verwendet.

Würden wir feststellen, dass das Berechnen der Statistiken nicht den gewünschten Effekt gebracht hat, die Abfrage nun ggf. sogar wesentlich langsamer läuft, könnten wir die eben berechneten Statistiken jetzt einfach wieder mit dbms_stats.delete_pending_stats verwerfen und auch die pending stats Session würde nun wieder den am Anfang gezeigten Ausführungsplan nutzen. Der gesamte Anwenderkreis außerhalb der „pending stats“ Session hätte nichts von all dem mitbekommen:

Abb.: pending stats

Wir wollen jedoch die neu berechneten Statistiken als global gültig setzen und veröffentlichen Sie daher per dbms_stats.publish_pending_stats:

Abb.: pending stats

Ab sofort nutzen alle Sessions diese Statistiken, auch die „global stats“ Session:

Abb.: global stats

Denken Sie bitte daran, die PUBLISH-Preference für die Tabelle im Anschluss wieder auf TRUE zu stellen, da sonst auch die Ergebnisse des nächtlich laufenden Autotask „auto optimizer stats collection“  für diese Tabelle nicht veröffentlicht würden. Es sei denn, sie wünschen genau das.

Abb.: pending stats

Fazit
Aktuelle Statistiken sind essentiell für verlässliche und performante Ausführungspläne. Nicht immer kommt man umhin, Statistiken oder Histogramme manuell nachzuberechnen, da sich z.B. die Defaultannahmen als unzutreffend erwiesen haben. Aufgrund der massiven Auswirkungen, die Änderungen an Statistiken oder Histogrammen auf Produktivsysteme haben können, sollten diese aber besser erst als pending statistics erstellt und vor der Freigabe geprüft werden.

Übrigens: Sollte bei der Berechnung der Statistiken doch einmal global „etwas schief gegangen“ sein – per dbms_stats.restore_*_stats können frühere Statistiken (standardmäßig bis zu 31 Tagen rückwirkend) wiederhergestellt werden.

Werfen Sie für weitere Informationen einfach einen Blick in die Dokumentation des dbms_stats-Package in „Oracle® Database PL/SQL Packages and Types Reference“ und in das Kapitel „Managing Optimizer Statistics“ des „Oracle® Database Performance Tuning Guide“.