Problème d'optimisation de requête suite à migration [Oracle ASM] - SQL/NoSQL - Programmation
Marsh Posté le 07-12-2006 à 16:02:41
que donne :
select t1.a, t1.b, t2.c
from t1 inner join t2 on t1.a = t2.a
where t1.b != t2.c
ou à la limite :
select t1.a, t1.b, t2.c
from t1 inner join t2 using a
where t1.b != t2.c
(sauf que je pige pas trop le coup du using... y'a une PK et c'est la syntaxe pour faire un natural join c'est ça ?)
Marsh Posté le 07-12-2006 à 16:06:16
En fait elle est assez simple : je croise mes tables sur un champ donné et je sélectionne seulement les lignes pour lesquels j'ai des valeur différentes sur un autre champ.
En gros je compare les données des deux tables pour trouver les différences...
Marsh Posté le 07-12-2006 à 16:09:20
MagicBuzz a écrit : que donne : |
A la base tes deux requêtes font la même chose que la mienne !
Une autre écriture serait :
select t1.a,t1.b,t2.c from
t1,t2
where t1.a = t2.a and t1.b != t2.c
C'est juste un souci d'optimisation et de rapidité d'écriture de la requête.
Marsh Posté le 07-12-2006 à 16:10:09
ben justement, je trouve que a syntaxe à toi est très bizarre. t'es sûr qu'elle est mieux ?
(chais bien que les sous-requête sont peut gênantes pour Oracle, mais là, une jointure sur deux sous-requêtes au lieu de faire une bête jointure, je trouve ça bizarre comme optimisation)
Marsh Posté le 07-12-2006 à 16:11:46
elle est mieux pour l'optimiseur qui connais directement les index à utiliser et pour l'espace utilisé en sort area car je récupère uniquement les données nécessaire dans mes sous requêtes.
Marsh Posté le 07-12-2006 à 16:12:24
chuis pas concaincu
mais bon, admettons que le problème ne vient pas de là, je suis d'accord.
aucune idée
en tout cas, au taff on est passé e 8i à 10gR2 et pareil, on a beau avoir un serveur 4 fois plus rapide, certains traîtements semble plus lents
Marsh Posté le 07-12-2006 à 16:13:28
petites précision, mes deux tables ont 50 champs différents de type varchar ou number pouvant aller de 10 à 50 caractères.
Marsh Posté le 07-12-2006 à 16:26:47
Je suis réellement pas convaincu par ta syntaxe :
|
=> Même résultats.
La première dure 3 secondes
La seconde dure 2 secondes
Cachune des deux requêtes a été éxécutée 4 fois de suite (en alternant à chaque fois)
Marsh Posté le 07-12-2006 à 17:11:16
En effet, en enlevant les sous requêtes je gagne en coût d'exécution (coût/2), par contre il fait un Table Access Full sans utiliser les index....
C'est bizarre ... En utilisant les indexes il est plus lent que sans !!!
Malheureusement j'en suis toujours pas à mon coût de mon ancien système...
Marsh Posté le 07-12-2006 à 17:12:49
ils sont comment tes index ? y'a pas une couille dans le potage ?
t'as une FK qui lie les deux champs A ?
Marsh Posté le 07-12-2006 à 17:19:42
nan, j'ai dit, pas de clé ni de contrainte !! les données sont pas unique dans chaque table ! seule la sous-requête renvoie des données du champs a unique.
J'ai lancé une version allégée de la requête écrite des 2 façon, on va bien voir ce que ca donne....
Marsh Posté le 07-12-2006 à 17:22:15
j'ai 1 index B-TREE sur le champ a de chacune de mes deux tables.
J'ai 1 index bitmap sur mes champs de condition de mes sous-requêtes.
Tout mes index sont partitionnés.
Marsh Posté le 07-12-2006 à 17:32:05
crée une vue qui fait la première sous-requête, et crée un index sur la vue. SQL Serveur le permet en tout cas.
Marsh Posté le 14-12-2006 à 20:49:02
rico90 a écrit : j'ai 1 index B-TREE sur le champ a de chacune de mes deux tables. |
si ils ne prend pas du tout tes index tu peux toujours hinter ta requete avec un /*+ index
je ne jouotte pas du tout avec la partie technique de oracle donc une migration asm je ne sais pas du tout ce que cela implique, mais tu as essayé de reanalyser tes index?
et aussi simplement voir si avec un simple select sur ta table sur laquelle tu mets ta clause where il utilise deja bien un index.
Marsh Posté le 07-12-2006 à 15:55:17
Bonjour,
Suite à une migration Oracle 9i vers 10g/ASM je rencontre un problème lors d'une requête de jointure de deux tables partitionnées.
Sur l'ancien serveur les deux tables étaient réparties sur six disques différents et les indexes inversés avec les données.
Sur le nouveau serveur les deux tables sont sur le même groupe ASM et les indexes sur un deuxième groupe ASM.
Le gain de performance entre les deux modes de stockage est de 50% en moyenne sauf pour la requête qui croise les deux tables.
Les données à croiser sont bien entendu indexées par le critère de jointure et n'ayant pas de clé ni de contraite sur mes tables que je peux créer de bitmap join index.
La différence de rapidité est impressionnante : je passe de 50 min à 10h pour croiser 5 MM (millions) de lignes !!
en gros la requête en question est la suivante :
select a,b,c from
(select a,b from T1)
inner join
(select a,c from T2)
using (a)
where b<>c
Sachant que T1 fait 35 MM de lignes et T2 fait 120 MM de lignes.
Voici les coûts de l'explain plan :
Ancien serveur :
Jointure 88 892
Lecture T1 798
Lecture T2 88 039
Nouveau serveur :
Jointure 3 109 628
Lecture T1 836 466
Lecture T2 2 235 198
Avez-vous déjà rencontré ce problème ? Avez-vous des idées d'optimisation ?
Merci,