Précédent   Forum des professionnels en informatique > Bases de données > Oracle > SQL
SQL Forum d'entraide sur le SQL pour Oracle
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 26/12/2007, 19h13   #1
Membre du Club
 
Étudiant
Inscription : avril 2007
Messages : 165
Détails du profil
Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : avril 2007
Messages : 165
Points : 40
Points : 40
Par défaut Appeler une fonction dans une close where !

Bonjour!
je me trouve face au beosins d'appeler une fonction dans une close where,
genre:
Code :
1
2
3
4
5
 
SELECT c1, c2, c3
FROM ma_premiere_table tab1,
       ma_deuxieme_table tab2
WHERE tab2.c3=ma_fonction(tab1.c3)

... ça m'apparait pas tres optimisé comme code...


alors votre avis !!?

Merci par avance.
PMS
widom est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/12/2007, 00h58   #2
Membre éprouvé
 
Inscription : décembre 2007
Messages : 354
Détails du profil
Informations personnelles :
Localisation : France

Informations forums :
Inscription : décembre 2007
Messages : 354
Points : 408
Points : 408
Il est impossible de se prononcer dans l'absolue de cette façon ...
Dans certains cas, il est effectivement possible d'écrire la requête sans faire recours à la fonction et il est concevable dans ce cas de considérer la fonction comme une mauvaise solution.

Il ne faut pas oublier non plus que les index basés sur des fonctions permettent de booster la perforlance ...
Michel SALAIS est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/12/2007, 13h58   #3
Membre du Club
 
Étudiant
Inscription : avril 2007
Messages : 165
Détails du profil
Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : avril 2007
Messages : 165
Points : 40
Points : 40
Citation:
Envoyé par Michel SALAIS Voir le message
Il est impossible de se prononcer dans l'absolue de cette façon ...
Dans certains cas, il est effectivement possible d'écrire la requête sans faire recours à la fonction et il est concevable dans ce cas de considérer la fonction comme une mauvaise solution.

Il ne faut pas oublier non plus que les index basés sur des fonctions permettent de booster la perforlance ...
Merci pour la reponse... mais

malheureusement je suis face à un cas où je n'ai pas de choix autre qu'une fonction...
Sauf que:
1- soit je crée une table d'une seule colonne , et la fonction alimentera alors cette table.... et donc j'interrogerai la table.
2- faire une table function... et donc faire des selects directement sur la fonction.... je sais que c'est faisable..; mais comment?
widom est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/12/2007, 15h51   #4
Membre éprouvé
 
Inscription : décembre 2007
Messages : 354
Détails du profil
Informations personnelles :
Localisation : France

Informations forums :
Inscription : décembre 2007
Messages : 354
Points : 408
Points : 408
Code :
1
2
3
4
5
 
SELECT c1, c2, c3
FROM ma_premiere_table tab1,
       ma_deuxieme_table tab2
WHERE tab2.c3=ma_fonction(tab1.c3)
Alors si la fonction est inévitable, et vu le code ci-dessus:
Créer un index basé sur la fonction. En gros

Code :
1
2
3
 
CREATE INDEX ...
ON tab1 (ma_fonction(c3))
Si c'est une fonction PL/SQL que vous définissez vous-même alors elle doit être déclarée DETERMINISTIC
Michel SALAIS est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/01/2008, 23h01   #5
Membre Expert
 
Homme
Expert Datawarehouses + BO (sur BDD Oracle et SQL Server)
Inscription : mars 2003
Messages : 645
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 41
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Expert Datawarehouses + BO (sur BDD Oracle et SQL Server)

Informations forums :
Inscription : mars 2003
Messages : 645
Points : 1 165
Points : 1 165
Pour privilégier des étapes bien séparées , je proposerais aussi la requête ci-dessous, à comparer avec la solution d'un index sur la fonction. (Mais c'est vrai qu'il vaut mieux éviter les jointures sur les fonctions en générale bien que les index sur fonctions existent depuis un certain nombre de version d'Oracle).


Code :
1
2
3
4
5
6
7
SELECT c1, c2, c3
FROM 
  (SELECT c1, ma_fonction(tab1.c3) c3_f
  FROM ma_premiere_table )
tab1
INNER JOIN    ma_deuxieme_table tab2
ON tab2.c3=tab1.c3_f

Comme ça, cela exécute la fonction pour chaque ligne lors du sous-SELECT, mais lors de la jointure le résultat de la fonction a déjà été calculée dans la sous-requête.
phili_b est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/01/2008, 23h12   #6
Membre éprouvé
 
Inscription : décembre 2007
Messages : 354
Détails du profil
Informations personnelles :
Localisation : France

Informations forums :
Inscription : décembre 2007
Messages : 354
Points : 408
Points : 408
Citation:
Envoyé par phili_b Voir le message
Pour privilégier des étapes bien séparées , je proposerais aussi la requête ci-dessous, à comparer avec la solution d'un index sur la fonction. (Mais c'est vrai qu'il vaut mieux éviter les jointures sur les fonctions en générale bien que les index sur fonctions existent depuis un certain nombre de version d'Oracle).


Code :
1
2
3
4
5
6
7
SELECT c1, c2, c3
FROM 
  (SELECT c1, ma_fonction(tab1.c3) c3_f
  FROM ma_premiere_table )
tab1
INNER JOIN    ma_deuxieme_table tab2
ON tab2.c3=tab1.c3_f

Comme ça, cela exécute la fonction pour chaque ligne lors du sous-SELECT, mais lors de la jointure le résultat de la fonction a déjà été calculée dans la sous-requête.
Ceci est discutable et Oracle peut choisir de faire autrement ...
Michel SALAIS est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/01/2008, 23h58   #7
Membre Expert
 
Homme
Expert Datawarehouses + BO (sur BDD Oracle et SQL Server)
Inscription : mars 2003
Messages : 645
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 41
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Expert Datawarehouses + BO (sur BDD Oracle et SQL Server)

Informations forums :
Inscription : mars 2003
Messages : 645
Points : 1 165
Points : 1 165
Je ne remets pas en cause ta solution qui est la meilleure si l'index sur la fonction est performant. Je propose simplement une alternative qui fonctionne pas trop mal si la création de l'index n'est pas possible ou non performant(= non discriminant par exemple).
phili_b est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/01/2008, 00h04   #8
Membre éprouvé
 
Inscription : décembre 2007
Messages : 354
Détails du profil
Informations personnelles :
Localisation : France

Informations forums :
Inscription : décembre 2007
Messages : 354
Points : 408
Points : 408
En fait et indépendamment de l'index basé sur la fonction, ce que je voulais dire que le calcul de la fonction dans ta requête n'est pas assuré de la façon que tu propose vu qu'Oracle peut faire la fusion d'une vue (requête imbriquée) dans la requête principale et alors il est nécessaire d'utiliser des hints ...
Michel SALAIS est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/01/2008, 00h08   #9
Membre Expert
 
Homme
Expert Datawarehouses + BO (sur BDD Oracle et SQL Server)
Inscription : mars 2003
Messages : 645
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 41
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Expert Datawarehouses + BO (sur BDD Oracle et SQL Server)

Informations forums :
Inscription : mars 2003
Messages : 645
Points : 1 165
Points : 1 165
Citation:
Envoyé par Michel SALAIS Voir le message
vu qu'Oracle peut faire la fusion d'une vue (requête imbriquée) dans la requête principale
ah ok ! je comprends mieux.
phili_b est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 16h49.


 
 
 
 
Partenaires

Hébergement Web