2009-07-13 13 views
4

In einer gespeicherten Prozedur (die ein Datum Parameter namens ‚paramDate‘ hat) Ich habe eine Abfrage wie dieseOracle Performance unter Verwendung von Funktionen in where-Klausel

select id, name 
from customer 
where period_aded = to_char(paramDate,'mm/yyyy') 

wird Oracle paramDate für jede Zeile in einem String konvertieren?

Ich war sicher, dass Oracle würde nicht, aber mir wurde gesagt, dass Oracle wird. In der Tat dachte ich, dass, wenn der Parameter der Funktion Constraint war (nicht innerhalb der Abfrage ein fierld noch ein berechneter Wert) das Ergebnis immer gleich sein sollte, und deshalb Oracle diese Konvertierung nur einmal durchführen sollte. Dann erkannte ich, dass ich manchmal DML-Sätze in mehreren Funktionen ausgeführt habe, und vielleicht könnte dies dazu führen, dass sich der resultierende Wert ändert, auch wenn er sich nicht für jede Zeile ändert.

Dies sollte bedeuten, dass ich solche Werte konvertieren sollte, bevor ich sie der Abfrage hinzufügen.

Wie auch immer, vielleicht gut 'bekannte Funktionen' (eingebaut) werden einmal ausgewertet, oder sogar meine Funktionen wären auch.

Auf jeden Fall wieder ...

Wird Orakel, dass to_char einmal ausführen oder wird Oracle tut es für jede Zeile?

Vielen Dank für Ihre Antworten

+0

Profilieren Sie die Abfrage und sehen Sie. –

Antwort

8

Ich glaube nicht, haben dies in der Regel der Fall ist, da es einen Index vor einer Nutzung verhindern würde.

Zumindest für integrierte Funktionen sollte Oracle in der Lage sein, herauszufinden, dass es nur einmal ausgewertet werden könnte. (Für benutzerdefinierte Funktionen, siehe unten). Hier

ist ein Fall, in dem ein Index verwendet wird (und die Funktion wird nicht für jede Zeile ausgewertet):

SQL> select id from tbl_table where id > to_char(sysdate, 'YYYY'); 

-------------------------------------------------------------------------------- 
| Id | Operation  | Name  | Rows | Bytes | Cost (%CPU)| Time  | 
-------------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT |    | 35 | 140 |  1 (0)| 00:00:01 | 
|* 1 | INDEX RANGE SCAN| SYS_C004274 | 35 | 140 |  1 (0)| 00:00:01 | 
-------------------------------------------------------------------------------- 

Predicate Information (identified by operation id): 
--------------------------------------------------- 

1 - access("ID">TO_NUMBER(TO_CHAR([email protected]!,'YYYY'))) 

Für benutzerdefinierte Funktionen lesen Sie in diesem article. Es nennt zwei Möglichkeiten, um sicherzustellen, dass Ihre Funktion nur einmal aufgerufen wird:

  1. Seit Oracle 10.2 können Sie die Funktion als DETERMINISTIC definieren.

  2. Bei älteren Versionen können Sie wieder Phrase es "skalare Unterabfrage Caching" zu verwenden:

    SELECT COUNT (*) FROM Mitarbeiter WHERE GEHALT = (SELECT getValue (1) FROM DUAL);

+0

+1, aber "deterministisch" ist in 9.2 verfügbar - ich benutze es dort schon. – l0b0

+0

Spät Danke, du hast meine Frage damals gelöst. –

1

Die Sorge um to_char mit mir eine Glocke läuten nicht. Doch in Ihrem PL/SQL, könnten Sie

create or replace procedure ........ 
    some_variable varchar2(128); 
begin 

    some_variable := to_char(paramDate,'mm/yyyy'); 

    -- and your query could read 

    select id, name from customer where period_aded = some_variable; 
. 
. 
. 
end; 
/

Kt

+0

Danke, ich habe versucht zu wissen, ob das etwas ist, das die SP-Leistung verbessern würde, das wäre der einzige Grund, alle vorhandenen zu ändern. Zum Glück scheint es nicht notwendig zu sein –

1

Mit Blick auf Zuschreibungen auf das deterministische Schlüsselwort (here is one, here is another) wurde eingeführt der Entwickler zu ermöglichen, Oracle zu sagen, dass die Funktion den gleichen Wert für den gleichen Eingang params zurückzukehren.Wenn Sie also möchten, dass Ihre Funktionen nur einmal aufgerufen werden, und Sie können garantieren, dass sie immer denselben Wert für die gleichen Eingabeparameter zurückgeben, können Sie das Schlüsselwort DETERMINISTIC verwenden.

In Bezug auf integrierte Funktionen wie to_char, schlage ich diejenigen, die besser in den Innereien von Oracle versiert sind, um Ihnen Richtung zu geben.

Verwandte Themen