|
Publicité ' | ||||||||||||||||||||||||
|
|
#1 | ||||||
|
Candidat au titre de Membre du Club
![]() Inscription : octobre 2006 Messages : 50 ![]() |
Bonjour,
Soit une requête du genre Code :
Maintenant, je voudrais appliquer un autre critère, du genre : Code :
Code :
Après exécution, la séquence vaut 90 000 et quelques, ce qui explique la lenteur, mais je ne comprends pas pourquoi on passe 90 000 fois dans cette fonction ! ![]() La question reste : comment faire pour qu'il n'exécute cette fonction que pour les 1600 enregistrements déjà sélectionnés pour la requête ? Je précise que si je supprime la jointure avec la table vide, le résultat de la requête reste le même (normal), mais la séquence vaut bien 1600 et la requête va vite ! ![]() Merci pour toute explication et idée pour booster cette requête ! |
||||||
|
|
00
|
|
|
#2 |
|
Expert Confirmé
![]() Inscription : septembre 2004 Messages : 2 942 ![]() |
quel schéma....
les indexes ne sont sûrement pas utilisés avec toutes ces fonctions en clause WHERE |
|
|
00
|
|
|
#3 |
|
Candidat au titre de Membre du Club
![]() Inscription : octobre 2006 Messages : 50 ![]() |
|
|
|
00
|
|
|
#4 |
|
Expert Confirmé
![]() Inscription : septembre 2004 Messages : 2 942 ![]() |
Si la question n'est pas d'améliorer les perfs, c'est quoi alors ?
|
|
|
00
|
|
|
#5 |
![]() ![]() Inscription : janvier 2004 Messages : 15 861 ![]() |
faudrait peut-être faire un index sur la fonction
|
|
|
00
|
|
|
#6 |
|
Candidat au titre de Membre du Club
![]() Inscription : octobre 2006 Messages : 50 ![]() |
C'est celle-ci : comment se fait-il que la fonction soit exécutée 90 000 fois alors qu'elle ne devrait s'appliquer qu'à la requête qui renvoit 1600 lignes ?
Ensuite, car je ne doute pas qu'il y ait une bonne raison, comment faire pour qu'elle ne s'applique réellement que 1600 fois ? |
|
|
00
|
|
|
#7 |
![]() ![]() Inscription : janvier 2004 Messages : 15 861 ![]() |
peut-être parce que la table à 90000 lignes non ?
Code :
comment faire pour qu'elle ne s'applique réellement que 1600 fois ? |
|
|
00
|
|
|
#8 |
![]() ![]() Inscription : janvier 2004 Messages : 15 861 ![]() |
Plutôt qu'un message qui sert à rien tu pourrais au moins donner des éléments comme le plan d'exécution et essayer l'index que j'ai proposé
j'imagine que les stats sont calculées ? Tu peux aussi donné le NUM_ROWS des tables non ? |
|
|
00
|
|
|
#9 |
|
Membre éprouvé
![]() Inscription : décembre 2007 Messages : 354 ![]() |
Il faut savoir que Oracle peut tenter de fusionner les vues dans la requête principale. Si tu veux empêcher la fusion alors il faut utiliser par exemple l'indicateur d'optimisation /*+ materialize */
|
|
|
00
|
|
|
#11 | |
|
Candidat au titre de Membre du Club
![]() Inscription : octobre 2006 Messages : 50 ![]() |
Citation:
Pour être franc, j'ai essayé et ça ne change pas grand chose, mais je ne sais pas trop où placer ce hint... |
|
|
|
00
|
|
|
#12 | |||
|
Candidat au titre de Membre du Club
![]() Inscription : octobre 2006 Messages : 50 ![]() |
Citation:
Mais, du coup, je me demande quel est le moyen "recommandé" de tourner une requête de ce genre ! Par exemple, admettons que je veuille appliquer une fonction assez coûteuse en temps seulement sur les filles. La requête de base serait Code :
Comment tournerais-tu cette requête pour utiliser ce hint NO_MERGE ? |
|||
|
|
00
|
|
|
#13 |
|
Expert Confirmé
![]() Inscription : septembre 2004 Messages : 2 942 ![]() |
j'en profite pour élargir le débat : l'utilisation des hints est très efficace et parfaitement normale d'utilisation mais il faut bien être conscient de ce que l'on fait !
C'est à dire que l'on fige "ad vitam eternam" l'application et donc le schéma. Ce qui est assez gênant dans bien des contextes. Je préfère utiliser des outline qui permettent de modifier le plan d'exécution mais sans que l'on ne touche aux requêtes générées par l'appli... http://download.oracle.com/docs/cd/B...htm#sthref3533 |
|
|
00
|
|
|
#14 |
|
Membre éprouvé
![]() Inscription : décembre 2007 Messages : 354 ![]() |
En fait materialize doit se positionner dans la requête interne et pas sur la requête externe mais comme l'a signalé pitfor no_merge est une autre possibilité
|
|
|
00
|
|
|
#15 | |
|
Membre éprouvé
![]() Inscription : décembre 2007 Messages : 354 ![]() |
Citation:
Pour aller encore plus loin, il peut être utile de collecter les stats système ce qui activera la prise en considération du cpu par l'optimiseur. Une solution qui éviterai le calcul coûteux de la fonction est d'utiliser un index basé sur cette fonction |
|
|
|
00
|
|
|
#16 | ||||
|
Candidat au titre de Membre du Club
![]() Inscription : octobre 2006 Messages : 50 ![]() |
Citation:
Citation:
Tu isolerais d'abord les filles, puis tu ferais leur moyenne. Oracle fait toutes les moyennes (enfin, pas toutes d'ailleurs, il en fait 90000 sur 150000, alors qu'il n'y a que 10000 filles) et cherche à rapprocher la liste des moyennes de la liste des filles. Le seul moyen que j'aie trouvé pour faire ce que je veux, c'est une fonction CAST qui, en gros, parcourt un curseur SELECT * FROM TABLE WHERE SEXE='F' et, pour chaque ligne trouvée, exécute la fonction et renvoie une ligne... Là, ça booste pile-poil et c'est normal, Oracle fait ce qu'on lui demande et c'est tout simple. Le code, pour info : Code :
|
||||
|
|
00
|
|
|
#17 | |
|
Membre éprouvé
![]() Inscription : décembre 2007 Messages : 354 ![]() |
Bon,
Que dis-tu de ça ? Citation:
|
|
|
|
00
|
|
|
#18 |
|
Expert Confirmé
![]() Inscription : septembre 2004 Messages : 2 942 ![]() |
sans compter, qu'il faut peut-être un peu faire confiance au CBO....
quelle est la différence de temps constaté entre sans rien et avec des hints ? |
|
|
00
|
|
|
#19 |
|
Candidat au titre de Membre du Club
![]() Inscription : octobre 2006 Messages : 50 ![]() |
je ne pense que du bien de tes propositions
Mais bon, celle-là, faut être franc, je n'y comprends rien ! Je suis quand même le débutant de base avec Oracle alors faut être patient... Mais de toutes façons, pour ce cas, s'il faut toucher au paramétrage d'Oracle, tu peux laisser tomber parce que je n'y ai pas accès chez le client. Je ne touche pas non plus au prog, il faut juste que la requête booste et c'est tout !
|
|
|
00
|
|
|
#20 | ||
|
Candidat au titre de Membre du Club
![]() Inscription : octobre 2006 Messages : 50 ![]() |
Citation:
Citation:
Une requête qui dure 40 secondes va peut-être passer à 38, mais rien ne me dit que c'est grâce aux hints car 2 minutes après elle prendra 42... La comparaison de référence se fait avec l'appel de la foncton CAST : environ 2 secondes, ce qui est tout à fait correct et conforme à ce qu'on peut attendre d'une requête qui fait un truc un peu compliqué sur 2500 enregistrements (parmi 150 000) environ. Le problème c'est que, même avec index, si Oracle exécute la fonction sur 90 000 enregistrements (d'où les sort-il ?), c'est normal que ça lui prenne du temps. Or, c'est idiot de l'exécuter sur 90 000 puisqu'au final, seuls 2500 enreg. sont concernés (euh... je me répète, là , non ? |
||
|
|
00
|
Copyright © 2000-2012 - www.developpez.com