Angenommen, Sie haben das folgende Update:
%Vor%Die Funktion func wird zweimal für jede Zeile oder einmal für jede Zeile ausgewertet?
Danke,
Dies ist die Art von Situation, in der einige Experimente nützlich sind (dies wurde mit 10 g durchgeführt). Mit der folgenden Abfrage können wir feststellen, dass normale Funktionen mit denselben Parametern (in diesem Fall keine) bei jedem Aufruf ausgeführt werden:
%Vor% Dies liegt daran, dass Oracle annimmt, dass eine Funktion den gleichen Wert nicht konsistent zurückgibt, wenn Sie es nicht anders angeben. Dazu können Sie eine Funktion mit dem Schlüsselwort deterministic
erstellen:
Diese Funktion anstelle von dbms_random
in der ersten Abfrage sagt uns, dass die Abfrage trotz der vielen Aufrufe nur einmal ausgeführt wird. Dies verdeutlicht jedoch nur den Abschnitt select
. Was, wenn wir dieselbe deterministische Funktion sowohl in einer select
als auch einer where
Klausel verwenden. Wir können das mit der folgenden Abfrage testen:
Sie müssen dies möglicherweise mehrere Male ausführen, um unseren Beweis zu sehen, aber schließlich sehen Sie eine Liste mit Werten unter 0,5. Dies gibt uns den Beweis, dass sogar die deterministische Funktion zweimal ausgeführt wird: einmal für jeden Abschnitt, in dem sie erscheint. Alternativ können Sie unsere deterministische Funktion wie folgt ändern und dann die nachfolgende Abfrage ausführen, die 2 Zeilen in% anzeigt. co_de%.
%Vor%Ich mag zwar Allans Antwort, um zu zeigen, wie man das untersucht, aber ich denke, die wahre Lektion ist, dass man sich nicht auf die Antwort auf diese Frage verlassen sollte, wenn man sie vermeiden kann.
Hier ist ein nützlicher Beitrag zum Thema Thema von Tom Kyte ("Ich habe tausende Male geschrieben, dass Sie sich nicht darauf verlassen können, wie oft oder wann oder ob SQL Ihre Funktion aufruft.") Schon bevor 11g den Ergebnis-Cache einführt, gibt es keine Garantie dafür, wie oft Eine Funktion wird bei der Verarbeitung einer SQL-Anweisung aufgerufen. Dies kann vom Ausführungsplan abhängen, der sich im Laufe der Zeit ändern kann.
Wenn es sich um Ihre Leistung handelt und Ihre Funktion deterministisch ist, reicht der 11g-Ergebniscache wahrscheinlich aus - sie garantiert keine spezifische Begrenzung der Anzahl der Aufrufe der Funktion, sollte jedoch die Anzahl der redundanten Aufrufe erheblich reduzieren. (Siehe Link in @cularis Antwort.)
Wenn Sie aus irgendeinem Grund sicherstellen wollen, dass die beiden Aufrufe an die Funktionen unterschiedlich sind, würde ich Ihnen wohl nur einen zweiten Parameter hinzufügen, der zwar ignoriert wird, aber dazu dient, das zu verhindern Ergebnis Cache oder Optimierer sehen die Anrufe als identisch.