Dienstag, Mai 26, 2015

Franck Pachot über SQL Plan Directives

In den letzten Wochen hat Franck Pachot eine Reihe interessanter Artikel zum Verhalten von SQL Plan Directives veröffentlicht, die ich an dieser Stelle grob vereinfachend zusammenfasse. Eine Einleitung zum Thema wollte ich mir eigentlich sparen, da ich etwas Derartiges hier bereits untergebracht hatte, aber der Herr Pachot hat es in Matching SQL Plan Directives and extended stats so schön zusammengefasst, dass ich mir seine Erklärung ausborge:
SQL Plan Directives in USABLE/MISSING_STATS state can create column groups and extended stats on it at the next dbms_stats gathering. When the next usage of the SPD validates that static statistics are sufficient to get good cardinality estimates, then the SPD goes into the SUPERSEDED/HAS_STATS state. If an execution still see misestimates on them, then the state will go to SUPERSEDED/PERMANENT and dynamic sampling will be used forever. Note that disabled SPD can still trigger the creation of extended statistics but not the dynamix sampling.
Die Artikel beschäftigen sich mit diversen Detailfragestellungen:
  • DBA_SQL_PLAN_DIRECTIVE.LAST_USED: weist darauf hin, dass die last_used-Angabe in der View nur eine sehr eingeschränkte Präzision besitzt und bei Verwendung um das eigenartige Inkrement 6,5 Tage erhöht wird.
  • Matching SQL Plan Directives and extended stats: leider gibt es keinen direkten Weg, um die Direktiven (aus DBA_SQL_PLAN_DIRECTIVES) mit den zugehörigen extended statistics (DBA_STATS_EXTENSION) zu verknüpfen, da sich das Format der gespeicherten Daten unterscheidet (XML bzw. CLOB). Man kann allerdings eine Query zum Parsen der Angaben formulieren und die Resultate dann joinen - und genau das hat der Herr Pachot auch getan. Außerdem formuliert er eine Reihe interessanter Fragen zum Umgang mit dem Feature, die aber keine definitive Antwort erhalten (können).
  • How to import SQL Plan Directives: zeigt, wie man Direktiven in eine Staging Tabelle packt, transportiert und andernorts wieder auspackt (wobei packen und entpacken über dbms_spd-Routinen realisiert sind). Das Verfahren ähnelt dem, das beim Transport von SQL Plan Baselines zu verwenden ist.
  • Matching SQL Plan Directives and queries using it: erläutert, dass es nicht ganz leicht ist, zu bestimmen, weil Direktive für welche Query verwendet wurde: explain plan (bzw. dbms_xplan.display) liefert diese Information, aber sie fehlt in v$sql_plan: "It's not easy to match all queries that can use a SQL Plan Directive, but you can do it on the other way: do an explain plan for each query you suspect and check the notes. If you are ready to parse a lot of queries, you can also do it automatically."
Offensichtlich beschäftigt sich Frank Pachot zur Zeit recht intensiv mit dem Thema, so dass ich vermute, dass da noch weitere Artikel zu erwarten sind, die ich gegebenenfalls zu ergänzen plane.

Donnerstag, Mai 21, 2015

Dom Brooks über Plan-Stabilität

Dom Brooks zählt zu den Blog-Autoren, die sich am intensivsten mit Fragen der Stabilität von SQL-Ausführungsplänen beschäftigt haben. In Strategies for Minimising SQL Execution Plan Instability liefert er einen recht umfassenden historischen Überblick zur Entwicklung des Optimizers und jener Ergänzungen, die eingeführt wurden, um seine Informationsgrundlagen und Entscheidungsmöglichkeiten zu erweitern. Dabei gilt natürlich, dass die größere Flexibilität und die Einführung adaptiver Strategien dazu führen, dass die Stabilität der Optimizer-Entscheidungen geringer wird. Die grundlegende Frage dabei ist: "Do you want the Optimizer to try to get a better execution plan sometimes? If the answer is yes, then you have to accept that it will get it wrong from time to time." Um die Stabilität von Plänen wieder zu erhöhen, wurden im Laufe der Zeit diverse Hilfsmittel eingeführt, vor allem SPM (SQL Plan Management) in 11g, die es erlauben, die Planauswahl des Optimizers zu kontrollieren und der Autor erläutert ausführlich, welche Möglichkeiten in diesem Zusammenhang existieren und wo ihre Einschränkungen liegen. Insgesamt liefert der Artikel eine ziemlich vollständige Liste der im Rahmen der Fragestellung der Stabilität/Instabilität von Plänen relevanten Faktoren.

Mittwoch, Mai 20, 2015

postgres Ressourcen

Mit den Links zu den - in der Regel sehr lesenswerten - Artikeln des dbi-services Blog habe ich manchmal nicht allzu viel Glück, weil sie bisweilen statt beim gewünschten Artikel auf der Latest Entry Seite ankommen (was laut Franck Pachot ein Joomla-Problem sein könnte - und demnächst erledigt sein sollte, da ein Umzug nach wordpress geplant ist). Trotzdem versuche ich es ein weiteres Mal mit einer Verlinkung: diesmal auf den Artikel "What will be coming with the next major version of postgresql?" von Daniel Westermann, der die einschlägigen Ressourcen zur postgres-Weiterentwicklung zusammenfasst, darunter vor allem auch:
Persönlich verfolge ich nur die Blogs, in denen letztlich alles interessanten Entwicklungen angesprochen werden.

Montag, Mai 18, 2015

Upsert in postgres

In meiner universitären Vergangenheit hätte ich es vielleicht "ein Desiderat der Forschung" genannt: ein Kommando, mit dessen Hilfe sich in postgres ein INSERT oder UPDATE in Abhängigkeit davon durchführen lässt, ob ein gegebener Schlüssel bereits in der Zieltabelle vorliegt. Diese in anderen Datenbanken als MERGE oder UPSERT bezeichnete Funktionalität ist seit vielen Jahren die wahrscheinlich größte Lücke im ansonsten sehr mächtigen SQL-Dialekt von postgres. Mit Release 9.5 wird diese Lücke nun offenbar endlich geschlossen - wobei sich die postgres-Entwickler dafür entschieden haben, die Option als Ergänzung des INSERT-Kommandos zu implementieren:
INSERT INTO ... VALUES ...
   ON CONFLICT
   DO UPDATE SET ...
Ein paar einführende Erläuterungen zum Verhalten liefern unter anderem Craig Kerstiens und Michael Paquier, vor allem aber Hubert Lubaczewski, der - wie üblich - die umfangreichste Untersuchung liefert und dabei auch die Performance betrachtet.

Dienstag, Mai 12, 2015

Degenerierte Indizes

Seit ich begonnen habe, mich mit Datenbanken zu beschäftigen, lautet eine der populärsten Fragen in Oracle-Foren: mit welcher Häufigkeit soll ich meine B*Tree-Indizes neu aufbauen lassen? Zu behaupten darüber hätten Kriege stattgefunden, wäre vielleicht ein wenig übertrieben - aber heftige Auseinandersetzungen waren es allemal. Inzwischen ist dieser Konflikt weitgehend zur Ruhe gekommen, was vermutlich damit zusammen hängt, dass die Antwort eigentlich unstrittig ist: Oracles Implementierung von Indizes macht Rebuilds weitgehend unnötig - sie sind nur für seltene Fälle mit besonderen Bedingungen für die zugehörigen DML-Operationen relevant. Richard Foote hat sich schon vor mehr als zehn Jahren in Oracle B-Tree Index Internals: Rebuilding The Truth mit den Aussagen der Befürworter von regelmäßigen Rebuild-Operationen auseinander gesetzt und diese widerlegt. Trotzdem findet man den Vorschlag solcher Rebuilds auch noch in jüngeren Publikationen, wobei die Formulierungen allmählich den Bereich unfreiwilliger Komik erreichen, was David Aldridge auf Richards Footes Webseite kommentierte:
Interesting quote from Page 728 of that book: “Even if index rebuilding were to be proven as [sic] a useless activity, the Placebo effect on the end users is enough to justify the task.”. It opens up a whole new class of performance tuning … perhaps it could be called “Faith-based Tuning”.
Jonathan Lewis schrieb dazu: "If the only effect is a placebo effect couldn’t you just tell the users that you had rebuilt the indexes rather than actually doing it?"

So viel zur Geschichte - wobei es sich aus meiner Sicht um Ausschnitte aus dem Kapitel zur Auseinandersetzung zwischen wissenschaftlicher und mythischer Welterklärung handelt. Aber der eigentliche Anlass für diesen Eintrag war ein anderer: Mohamed Houri hat gerade einen Artikel zu seiner Verwendung des Scripts Index Sizing von Jonathan Lewis veröffentlicht, mit dessen Hilfe er einen jener seltenen degenerierten Indizes identifizieren konnte, die tatsächlich von einem Rebuild profitieren - alles deutlich komprimiert werden können. Letztlich leistet das Skript dabei nicht mehr (und nicht weniger), als die tatsächliche Größe eines Index mit der angesichts des Datenvolumens erwartbaren Minimalgröße zu vergleichen. Mohamed ergänzt dieses Ergebnis in seinem Artikel um eine Visualisierung der durch die Funktion sys_op_lbid ermittelten Anzahlen von Index-Einträgen pro Leaf-Block und diese Darstellung zeigt, dass es neben einer großen Zahl gut gefüllter Blocks (mit 422 Einträgen) eine noch größere Anzahl relativ schwach gefüllter Blöcke (mit 113 Einträgen) gibt. In seinem Kommentar zum Artikel erinnert Jonathan Lewis wiederum daran, dass hier womöglich das bekannte Problem der Vervielfältigung von ITL Einträgen im Spiel ist, das in solchen Fällen regelmäßig aufzutreten pflegt.

Vielleicht hätte ich mir (und meinen vorgestellten Lesern) den historischen Einstieg auch ersparen können, aber offenbar habe ich inzwischen das Alter erreicht, in dem man beginnt, von den alten Zeiten zu schwadronieren, in denen alles besser/schlechter/anders gewesen ist.