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.
Keine Kommentare:
Kommentar veröffentlichen