Montag, Juni 20, 2016

Typ-Konvertierung und cardinality-Schätzung

Jonathan Lewis weit in seinem Scratchpad darauf hin, dass Funktionsaufrufe für Spalten im Fall einer Bedingung "function(column) = constant" üblicherweise zu einer Schätzung von 1% führen. Dies gilt aber nicht für einfache Typ-Umwandlungen: eine Bedingung in der eine Charakter-Spalte mit einem numerischen Wert verglichen wird, verwendet eine Variante der Standardformel zur Berechnung gleichverteilter Werte, nämlich (Anzahl Werte)/(Anzahl distinkter Werte) - wobei die Klassifizierung als Variante damit zusammenhängt, dass die Anzahl distinkter Werte in einer Charakter-Spalte nicht zwingend der Anzahl der in ihr repräsentierter numerischer Werte entspricht, da 9 als '9' und '09' und beliebig viele andere Strings dargestellt werden kann. Für eine String-Spalte v1 liefert demnach folgende Bedingung eine cardinality auf Basis der Standardformel:
where to_number(v1) = 9
Wobei das to_number keine Rolle spielt, denn "where v1 = 9" wird genauso behandelt. Will man den Optimizer in einem solchen Fall weiter verwirren und die 1%-Schätzung für "function(column) = constant" zurückbekommen, dann kann man eine weitere Funktion ins Spiel bringen. Mit:
where sign(v1) = 1
bekommt man diese 1%-Schätzung, da der Optimizer in diesem Fall keine Vorstellung davon hat, was die sign-Funktion eigentlich tut. Ob man das irgendwo praktisch nutzen kann, sei mal dahingestellt - aber es zu wissen, kann sicher nicht schaden.

Natürlich funktionieren alle Beispiele nur so lange, wie v1 tatsächlich nur Repräsentationen numerische Werte enthält - und dann wäre es vermutlich naheliegend die Spalte gleich mit dem richtigen Datentyp auszustatten.

Montag, Juni 06, 2016

Merge Operationen und überflüssige Spalten.

Vor ein paar Jahren hatte ich hier einen Artikel von Alexander Anokhin verlinkt, in dem erläutert wurde, dass die in der USING clause eines Merge verwendeten Spalten selbst dann in die workarea aufgenommen werden müssen, wenn sie weder im ON noch in der UPDATE-Spaltenliste erscheinen - obwohl es eigentlich durch eine semantische Analyse möglich sein sollte zu bestimmen, dass man diese Spalten gefahrlos ausklammern könnte. Jetzt hat Jonathan Lewis auf einen naheliegenden anderen Aspekt dieses Effekts hingewiesen: dadurch, dass die Spalten in der Projection berücksichtigt werden, ist auch die Verwendung eines Index Fast Full Scans anstelle eines Full Table Scans nicht möglich, wenn zwischenzeitlich Spalten benötigt werden, die für die funktionale Ausführung der Operation eigentlich keine Rolle spielen.

Sonntag, Juni 05, 2016

SQL Server Wait Typen und Latch Klassen

Zwei großartige Hilfsmittel hat Paul Randal vor wenigen Wochen in seinem Blog bekannt gemacht:
  • SQL Server Wait Types Library: eine Liste mit den seit Version 2005 im SQL Server vorkommenden Wait Typen und Erklärungen zu ihrer Bedeutung, ihrer Verfügbarkeit, ihrer Beziehung zu des Extendes Events, sowie Informationen zum Troubleshooting.
  • SQL Server Latch Classes Library: mit entsprechenden Informationen zu den Latch Klassen.
Diese Links könnten mir allerlei Suchoperationen in Books Online ersparen.

Mittwoch, Juni 01, 2016

Datentypauswahl für Datumsangaben und ihre Wirkung auf den CBO

In Cost Based Oracle hat Jonathan Lewis dieses Thema bereits umfassend erläutert: Datumswerte sollten mit dem Datentyp DATE gespeichert werden, da der Optimizer nur für diesen Datentyp das Wissen besitzt, dass es zwischen den Monats- und Jahreswechseln keine großen Lücken gibt - dass also auf to_date('31.12.2016', 'dd.mm.yyyy') als nächster Tag to_date('01.01.2017', 'dd.mm.yyyy') folgt; und nicht 20161232 nach 20161231. Insofern enthält die aktuelle Artikelserie von Richard Foote zum gleichen Thema keine grundsätzlich neuen Einsichten, aber lesenswert sind die Artikel des Herrn Foote immer und man kann bei Bedarf gut darauf verlinken, so dass ich sie hier einfach aufliste:

    Freitag, Mai 27, 2016

    CBO Transformationen für count distinct Operationen

    Anfang 2014 hatte ich hier einen Artikel angesprochen, der im High-Performance Blog von Persicope erschienen war und versprach, postgres Queries mit einer count distinct Operation um den Faktor 50 zu beschleunigen. Ich hatte damals selbst ein paar Tests mit Oracle durchgeführt, die zeigten, dass die Umformulierung auch dort nützlich ist, aber weitaus weniger dramatische Effekte hervorruft als bei postgres (was kurz darauf in einem weiteren Artikel bei Periscope ebenfalls angemerkt wurde. Außerdem hatte ich einen Artikel von Hubert Lubacewski verknüpft, in dem dieser zeigte, dass man durch geschicktere Umformulierung in postgres noch sehr viel mehr erreichen kann als mit den periscope-Varianten.

    Jetzt hat Jonathan Lewis im Scratchpad auf den Artikel verwiesen und dabei gezeigt, dass der CBO für einfachere Beispiele durchaus dazu in der Lage ist, diese Umformung selbständig durchzuführen. Verwendet werden dabei folgende Optimizer-Transformationen:
    • place group by: verfügbar ab 11.1.0.6 (2007)
    • transform distinct aggregation: verfügbar seit 11.2.0.1 (2009)
    Wie üblich ist der Optimizer aber nicht in jedem Fall dazu in der Lage, die richtige Strategie auszuwählen, so dass man ihn manchmal durch Hints auf die richtige Spur bringen muss (hier etwa: no_transform_distinct_agg).