[Oracle ASM] Problème d'optimisation de requête suite à migration

Problème d'optimisation de requête suite à migration [Oracle ASM] - SQL/NoSQL - Programmation

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,

Reply

Marsh Posté le 07-12-2006 à 15:55:17   

Reply

Marsh Posté le 07-12-2006 à 16:00:56    

je pige pas trop ta requête, mais je la trouve bizarre :??:

Reply

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

Reply

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...

Reply

Marsh Posté le 07-12-2006 à 16:09:20    

MagicBuzz a écrit :

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


 
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.

Reply

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)


Message édité par MagicBuzz le 07-12-2006 à 16:11:22
Reply

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.

Reply

Marsh Posté le 07-12-2006 à 16:12:24    

chuis pas concaincu :p
 
mais bon, admettons que le problème ne vient pas de là, je suis d'accord.
 
aucune idée :spamafote:
 
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 :pt1cable:


Message édité par MagicBuzz le 07-12-2006 à 16:13:29
Reply

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.

Reply

Marsh Posté le 07-12-2006 à 16:26:47    

Je suis réellement pas convaincu par ta syntaxe :
 


select a, b, c
from
(
 select p2.codpro a, p2.numpos b
 from evp p2
 where p2.codsoc = 2
)
inner join
(
 select p4.codpro a, p4.numpos c
 from evp p4
 where p4.codsoc = 4
)
using (a)
where b != c
 
select p2.codpro, p2.numpos, p4.numpos
from evp p2 inner join evp p4 on p4.codpro = p2.codpro
where p2.codsoc = 2
and p4.codsoc = 4
and p4.numpos != p2.numpos


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

Reply

Marsh Posté le 07-12-2006 à 16:26:47   

Reply

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...

Reply

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 ?

Reply

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....

Reply

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.

Reply

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.

Reply

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.
J'ai 1 index bitmap sur mes champs de condition de mes sous-requêtes.
 
Tout mes index sont partitionnés.


 
 
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.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed