Dienstag, April 17, 2018

Keine Empfehlung mehr für System Statistics

Die Einführung der "System Statistics" liegt schon einige Jahre zurück, aber die ihnen zugrunde liegende Idee einer Kalibrierung der verfügbaren CPU- und I/O-Ressourcen fand ich damals durchaus einleuchtend. Tatsächlich eingesetzt habe ich sie selten - und das scheint inzwischen kaum noch jemand zu tun. Und zukünftig wird es wohl noch seltener vorkommen, nachdem Maria Colgan und Nigel Bayliss davon abraten. Bei Frau Colgan liest man:
Don’t gather system statistics unless you are in a pure data warehouse environment, with a good IO subsystem (e.g. Exadata) and you want to encourage the Optimizer to pick more full table scans and never says never!
Und der Herr Bayliss erklärt:
if you are at a decision point and you need to choose whether to gather them or not, then in most cases you should use the defaults and not gather system statistics.
Der Artikel von Nigel Bayliss erläutert auch noch mal genauer, was System Statistics eigentlich sind, wann sie eingeführt wurden (2001 mit 9i) und welche Empfehlungen dazu zu früheren Zeitpunkten gegeben wurden. Das Fazit lautet:
You might find that it is better to free yourself from managing system statistics and, instead, use the tools that Oracle provides you with to tune the queries that are not performing as well as you want.
Insofern gehört dieses Feature inzwischen offenbar zu den historischen.

Nachtrag 18.04.2018: in einem weiteren Artikel weist Maria Colgan darauf hin, dass die "Fixed Object Statistics" der x$-Objekte seit 12.1 im Rahmen der automatischen Statistikerfassung erzeugt werden. Allerdings werden sie nicht automatisch aktualisiert, so dass sie im Fall massiver Änderungen an Datenbank und Applikation manuell neu erzeugt werden sollten.

Mittwoch, April 11, 2018

Histogramm-Probleme mit EXP/IMP in Oracle 12

Jonathan Lewis weist darauf hin, dass die historischen Utilities exp und imp mit 12c neue Probleme bekommen haben: der Code der Tools wurde nicht dahingehend angepasst, dass sie mit den neuen Histogrammtypen "Hybrid" und "Top-N" zurecht kämen. Wenn man aus einem Quellsystem exportiert, in dem bereits ein "Hyrid Histogram" exisitiert, so wird dieses nach dem Import im Zielsystem zum historischen "Frequency Histogram" - das noch nie viel getaugt hat. Grundsätzlich sollte natürlich in diesen Tagen niemand mehr mit exp und imp hantieren, aber manchmal passiert das ja doch noch.

Donnerstag, April 05, 2018

Potentielle Performance-Probleme bei match_recognize

Jonathan Lewis hat vor einiger Zeit zwei Artikel zum match_recognize geschrieben, die auf potentielle Probleme hinweisen, die das Feature mit sich bringt, wenn man die Match-Bedingung nicht mit ausreichender Sorgfalt definiert. Leider gehört match_recognize noch immer nicht zu meinem SQL-Repertoire (jedenfalls nicht ohne dass ich mir irgendwo ein funktionierendes Beispiel ausborge und darin dann anpasse, bis es meinen Anforderungen entspricht), aber die Hinweise finde ich hier möglicherweise besser wieder als beim Herrn Lewis:
  • Match_recognize: erläutert das grundsätzliche Verhalten anhand eines Beispiel, in dem aus einer Menge die Kunden gesucht werden, die im September, nicht aber im Oktober eingekauft haben. Auf der Basis einer Menge mit 100K rows für September und einem Datensatz für Oktober und mit sehr breiten Datensätzen ergeben sich zwei Beobachtungen:
    • es ergeben sich unter Umständen sehr große Sortierungen (Anzahl Input rows * Gesamtlänge des Outputs der Spalten aus "partition by" und "measures").
    • wenn am Ende einer langen Sequenz von rows der letzte Datensatz nicht gematcht werden kann, geht Oracle zurück zum ersten Datensatz nach dem Start des vorangehenden Match-Versuchs. Stew Ashton weist in einem Kommentar darauf hin, dass das Problem noch größer ist, und mit diesem Hinweis beschäftigt sich der zweite Artikel zum Thema.
  • Match_recognise – 2: führt Stew Ashtons Hinweis weiter aus: in der ursprünglichen Version führt die Klausel nicht zu einem einmaligen Rücksprung, sondern zu einer iterativen Wiederholung, die bald zu extremen Laufzeiten führt. Wenn man die pattern-Klausel um ein vorangestelltes caret-Symbol (also: ^) erweitert, ändert man die Anforderung so, dass das Pattern mit der ersten row der Partition beginnen muss, was die Laufzeit im Beispiel von 250 auf weniger als eine Sekunde reduziert, weil damit die Wiederholung entfällt.
Sollte der Leser an dieser Stelle den Eindruck gewonnen haben, dass ich nicht so ganz verstanden habe, was ich da zusammenfasse, dann kann ich versichern: ich habe nicht ganz verstanden, was ich da zusammenfasse. Aber ich hoffe, bei erneuter Auseinandersetzung mit dem Thema allmählich dahinter zu kommen.

Donnerstag, März 22, 2018

Local Partitioned Indexes mit postgres 11

Daniel Westermann weist darauf hin, das postgres 11 erweiterte Optionen für die Indizierung partitionierter Tabellen liefern. Während in postgres 10 Indizes noch auf Partitionsebene erzeugt werden mussten, kann man sie jetzt für die partitionierte Tabelle definieren, was dazu führt, dass sie automatisch in den untergeordneten Partitionstabellen erzeugt werden. Vielleicht noch interessanter ist die Möglichkeit, primary keys auf partitionierten Tabellen zu erzeugen. Insgesamt ist deutlich zu erkennen, dass die Partitionierung in postgres allmählich ihre Kinderkrankheiten hinter sich lässt.

Nachtrag 26.03.2018: zu den Ergänzungen gehört auch das row movement - also die Verschiebung eines Datensatzes in eine andere Partition bei Änderung des Werts für den partition key. Auch dazu hat der Herr Westermann einen Artikel geschrieben.

Nachtrag 04.04.2018: und noch etwas, das in postgres 11 funktioniert: die postgres-Variante zum Merge-Statement - das "Insert ... on conflict".  Auch dazu hat der Herr Westermann einen Artikel geliefert.

Montag, März 12, 2018

Postgres: GIN-Indizes und Vacuum

Hans-Jüregen Schönig erläutert in seinem Blog die Rolle der "GIN Pending list" für die Performance von GIN-Indizes. Dazu erläutert er zunächst den Aufbau von GIN-Indizes: diese Indizes bestehen aus einem normalen B*Tree-Index, an den ergänzend ein "posting tree" angehängt ist. Der B*Tree-Index enthält auf Leaf-Ebene einen Eintrag für jedes indizierte Wort, aber die Zuordnung der Wörter zu den pages der zugehörigen Tabelle wird in eine weitere Struktur ausgelagert. Die Verweise in dieser zusätzlichen "posting tree" Struktur werden sortiert gespeichert, so dass eine Anpassung der Struktur potentiell teuer sein kann. Um diese Kosten zu verteilen, werden neue oder geänderte Einträge nicht unmittelbar an die richtige Stelle gebracht, sondern in eine "GIN pending list" ergänzt, die zusätzlich zur Indexstruktur sequentiell gelesen werden muss. Die Zusammenführung von "posting tree" und "pending list" ist Aufgabe des vacuum-Prozesses. Somit können massive DML-Operationen einen signifikanten Einfluss auf die Performance nachfolgender Zugriffe haben, die erfolgen, ehe der nächste Vacuum-Lauf wieder für Ordnung sorgt.