Mittwoch, März 29, 2017

Index Statistiken und Column Group Statistiken (Extended Statistics)

Nach einiger Zeit widme ich mich mal wieder einem meiner Hobbies: der Zusammenfassung des aktuellen Artikels von Jonathan Lewis. Diesmal geht es darum, dass der Herr Lewis gerne den - von mir häufig wiederholten - Vorschlag macht, bei der Löschung eines aus Zugriffssicht überflüssigen Index entsprechende "extended statistics" für die fragliche column group anzulegen, da der Optimizer die distinct key Angabe eines Index zur Durchführung eines Sanity Checks bei der cardinality-Bestimmung verwenden kann - was die Beurteilung von Index-Löschungen grundsätzlich schwieriger macht als die der Neuanlage von Indizes. Außerdem hat der Autor gelegentlich darauf hingewiesen, dass column group Statistiken dann Probleme bereiten (so heißen: nicht berücksichtigt werden), wenn die Einschränkung für eine der fraglichen Spalten außerhalb des Bereichs der für diese Spalte bekannten Werte liegt (also außerhalb des Korridors von low_value und high_value in user_tab_columns). Im aktuellen Artikel bringt er diese beiden Beobachtungen zusammen und stellt die Frage: kann die Löschung eines Index und Anlage von entsprechenden column group Statistiken im Fall derartiger Prädikate zu einer Veränderung der cardinality Schätzung führen. Dazu gibt es wie üblich ein Test-Beispiel: diesmal mit einer Tabelle mit zwei Spalten mit vollständig korrelierenden Werten, was ohne den Index oder die column groups in jedem Fall zu massiven Fehleinschätzungen des Optimizers führen würde. Auf dieser Basis werden drei Queries ausgeführt:
  • eine Query mit Index und zwei Prädikaten innerhalb des Ranges der bekannten Werte
  • eine Query mit Index und zwei Prädikaten außerhalb des Ranges der bekannten Werte
  • eine Query ohne Index - aber mit column group Statistiken - und zwei Prädikaten außerhalb des Ranges der bekannten Werte
 Die Ergebnisse zeigen für die drei Fälle:
  • für die erste Query werden die distinct keys des Index als Sanity Check bei der Kalkulation der Cardinality verwendet: dadurch ergibt sich ein Full Table Scan.
  • für die zweite Query werden die individuellen Selektivitäten der Spalten verwendet und jenseits des bekannten Wertebereichs setzt die übliche Abnahme der erwarteten Trefferwahrscheinlichkeit ein (linear decay): dadurch ergibt sich ein Index Zugriff.
  • für die dritte Query ergibt sich wieder der Full Table Scan.
Für den Herrn Lewis ergibt sich daraus: "So my concern that substituting column groups for indexes was unfounded – the optimizer was being silly (legal disclaimer: that’s just my opinion) with indexes, and the silly (ditto) behaviour with column groups hasn’t changed anything." Mir ist diese Antwort noch nicht ganz klar, da mein Eindruck ist, dass sich column group und der Index hier nicht zu den gleichen Ergebnissen führen - aber möglicherweise entgeht mir hier etwas Entscheidendes. Möglicherweise bekomme ich dazu noch eine Erklärung, die ich dann hier ergänzen würde.

Nachtrag vom gleichen Tag: Jonathan Lewis hat's erklärt: "The second and third plans both have a cardinality of 79 (which is the only thing the note was about). Were you looking at the cost, perhaps?" Tatsächlich hatte ich auf die cost-Angaben geschaut...

Mittwoch, März 22, 2017

Formatter-Einstellung für SQLcl

Dass die Häufigkeit meiner Beiträge zuletzt weiter abgenommen hat, mag dem regelmäßigen Leser aufgefallen sein und dafür gibt es - wie in solchen Fällen üblich - berufliche und private Ursachen (im weitesten Sinne steht Arbeit im Weg). Um aber nicht völlig zu verstummen hier mal wieder ein Link: Jeff Smith erläutert in seinem Blog, wie man eine SQL-Query in SQLcl mit dem Befehl "format buffer" automatisch formatieren lassen kann. Zusätzlich zeigt er, dass man die Regeln des Formatters im SQL Developer bearbeiten, in eine Datei exportieren und von SQLcl einlesen lassen kann: damit lässt sich die Formatierung dann den eigenen Wünschen entsprechend anpassen. Es wird wirklich Zeit, dass ich SQLcl zu meinem Standard CLI mache (und SQL*Plus nach wenigen Jahrzehnten hinter mir lasse).

Freitag, März 10, 2017

Serielle und parallele Update-Verarbeitung

Jonathan Lewis hat gestern in seinem Scratchpad danach gefragt, wie es dazu kommen kann, dass ein anscheinend parallelisierbares Update seriell verarbeitet wird, und stellt dazu ein umfangreiches Beispiel zur Verfügung. Die richtige - oder zumindest eine weitgehend richtige - Antwort auf die Quizfrage hat offenbar Franck Pachot geliefert, der darauf hinweist, dass ein paralleles Update in 12.1 für Tabellen mit SecureFile LOBs nur möglich ist, wenn die Tabelle partitioniert ist. Der Herr Lewis bestätigte die Vermutung, dass in seinem Beispiel eine als UNUSED markierte CLOB-Spalte im Spiel war, die in der Objekt-Definition nicht mehr sichtbar war (jedenfalls nicht via dbms_metadata oder in user_lobs; nur user_tab_cols liefert noch einen Eintrag mit einem "date and time" Namen). Außerdem wies er darauf hin, dass die Dokumentation hinsichtlich der existierenden Einschränkungen nicht besonders hilfreich ist, da es:
  • sie nicht alle erwähnt
  • einige schlecht beschreibt
  • und einige nennt, die nicht zutreffen
Außerdem verschwiegt die Dokumentation, welche Meldung dazu im Ausführungsplan erscheint ("PDML disabled because single fragment or non partitioned table used"). Das Szenario ist nicht unbedingt eines, von dem ich mich unmittelbar bedroht fühle, aber hier zeigt sich mal wieder, dass die Dokumentation der Features und Einschränkungen des eigenen Produkts nicht zu Oracles Kernkopetenzen zählt.

Freitag, März 03, 2017

Oracle 12.2 VM

Dass Oracle 12.2 (endlich) zum download verfügbar ist, konnte man dieser Tage bereits in jedem Oracle-Blog lesen. Nett finde ich aber insbesondere, dass es dazu gleich auch eine Virtual Box Appliance gibt - worauf Jeff Smith hinweist. Da ich die Installation auf Dauer nicht so sagenhaft spannend finde, bin ich dafür durchaus dankbar.