2009-07-13 8 views
4

Dans une procédure stockée (qui a un paramètre de date nommé « paramDate ») J'ai une requête comme celle-ciperformances d'Oracle en utilisant des fonctions dans la clause where

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

va Oracle convertir paramDate à chaîne pour chaque ligne?

J'étais sûr que Oracle ne le ferait pas mais on m'a dit que Oracle le fera. En fait, je pensais que si le paramètre de la fonction était contrainte (pas de valeur féroce ni de valeur calculée dans la requête), le résultat devrait toujours être le même, et c'est pourquoi Oracle ne devrait effectuer cette conversion qu'une seule fois. Puis j'ai réalisé que j'ai parfois exécuté des phrases DML dans plusieurs fonctions, et peut-être que cela pourrait changer la valeur résultante, même si ça ne change pas pour chaque ligne.

Cela devrait signifier que je devrais convertir ces valeurs avant de les ajouter à la requête. Quoi qu'il en soit, peut-être bien que les «fonctions connues» (intégrées) sont évaluées une fois, ou même mes fonctions le seraient également.

Quoi qu'il en soit, encore une fois ...

Est-ce que l'oracle exécuter to_char une ou Oracle va le faire pour chaque ligne?

Merci pour vos réponses

+0

Afficher la requête et voir. –

Répondre

8

Je ne pense pas que ce soit généralement le cas, car il empêcherait un indice d'être utilisé.

Au moins pour les fonctions intégrées, Oracle devrait être capable de comprendre qu'il ne pourrait l'évaluer qu'une seule fois. (Pour les fonctions définies par l'utilisateur, voir ci-dessous).

Voici un cas où un indice est utilisé (et la fonction n'est pas évaluée pour chaque ligne):

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'))) 

Pour les fonctions définies par l'utilisateur vérifier ce article. Il mentionne deux façons d'assurer que votre fonction est appelée une seule fois:

  1. Depuis Oracle 10.2, vous pouvez définir la fonction comme déterministes.

  2. sur les anciennes versions, vous pouvez re-phrase à utiliser "la mise en cache de sous-requête scalaire":

    SELECT COUNT (*) DE SALARIÉS = SALAIRE OU (SELECT getValue (1) DOUBLE);

+0

+1, mais "déterministe" est disponible en 9.2 - Je l'utilise déjà. – l0b0

+0

En retard merci, vous avez résolu ma question à l'époque. –

1

La préoccupation au sujet to_char ne sonne pas une cloche avec moi. Cependant, dans votre pl/sql, vous pourriez avoir

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

Merci, j'essayais de savoir si c'est quelque chose qui améliorerait les performances du SP, ce serait la seule raison d'aller changer tous les existants. Heureusement, il semble ne pas être nécessaire –

1

Regarder write-ups sur le mot-clé déterministes (here is one, here is another), il a été introduit pour permettre au développeur de dire que la fonction Oracle retourne la même valeur pour les mêmes params d'entrée.Donc, si vous voulez que vos fonctions soient appelées une seule fois, et vous pouvez garantir qu'elles retourneront toujours la même valeur pour les mêmes paramètres d'entrée vous pouvez utiliser le mot-clé DETERMINISTIC. En ce qui concerne les fonctions intégrées comme to_char, je m'en remets à ceux qui sont mieux versés dans les entrailles d'Oracle pour vous orienter.

Questions connexes