Précédent   Forum des professionnels en informatique > Bases de données > Oracle
Oracle Forum Oracle : le serveur, les outils, ... Voir F.A.Q Oracle Tutoriels 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 15/10/2007, 14h59   #1
Membre Expert
 
Homme
Consultant J2EE
Inscription : octobre 2007
Messages : 889
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Consultant J2EE

Informations forums :
Inscription : octobre 2007
Messages : 889
Points : 1 364
Points : 1 364
Par défaut UNION - Probleme de doublons

Bonjour a tous, petit nouveau ici mais je compte bien m'installer


Je suis actuellement en stage et fais du J2EE (Swing) (bon ok on s'en fou un peu c'est pas le sujet) et j'ai un probleme de doublons lors d'une requete avec Union sur une db oracle.

Je m'explique: je travaille sur une base de donnée qui est en sorte dédoublée: cad qu'en gros il y a sur le meme serveur oracle 2 bases identiques (les tables ont des prefixes exemple B1_TABLE et B2_TABLE contiennent les champs (meme type etc), mais pas les memes données !!!


En gros je suis amené a rechercher des informations dans ces deux tables en meme temps, en gros faire la meme requete sur les 2 tables, puis faire une union... seulement comme je le précise, les données ne sont pas exactement les memes ce qui fait que lors de mon union je me retrouve avec des resultats du genre:


CLEPRIMAIRE DATA
------------ -----
123 D1 (ligne issue de la B1)
123 D2 (ligne issue de la B2)


Seulement il faudrait que je puisse récupérer uniquement la ligne de la B1 si jamais elle existe, et sinon récupérer celle de la D2 (en fait plus exactement, selon la valeur d'un champ statut dans la B2, je dois récupérer l'une ou l'autre des 2 lignes)


Bref je voulais savoir s'il n'existait pas une solution relativement simple et optimisée pour ce genre de cas qui permettrait d'éliminer les doublons selon des champs spécifiés (clé primaire ici par exemple) plutot que sur l'ensemble des résultats... Sachant que ma requete de base est deja assez lourde il me faut vraiment quelque chose d'optimisé (je récupere une 50aine de champs sur une base avec plusieurs centaines de milliers de lignes, alors je suppose que tout traitement en java sur les objets récupérés est a excluse ^^)



Je ne suis pas un pro du sql, désolé si ma question vous semble idiote
HerQuLe est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/10/2007, 15h11   #2
Membre actif
 
Avatar de Loyd1974
 
Inscription : août 2007
Messages : 176
Détails du profil
Informations forums :
Inscription : août 2007
Messages : 176
Points : 172
Points : 172
Tu peux faire :
Code :
1
2
3
4
5
6
7
8
9
10
SELECT ...
FROM TABLE1 T1
WHERE ...
UNION ALL
SELECT ...
FROM TABLE2 T2
WHERE ...
AND NOT EXISTS (SELECT 1 FROM TABLE1 T1 WHERE T1.KEY = T2.KEY)
...
Si tu n'as pas de doublon au sein de tes 2 tables (c'est à dire que ta clef est vraiment unique au sein de chaque table), tu économises le coût du sort unique du UNION (remplacé par un UNION ALL) qui pourrait compenser un peu le cout de la recherche NOT EXISTS
Loyd1974 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/10/2007, 15h19   #3
Membre actif
 
Avatar de Loyd1974
 
Inscription : août 2007
Messages : 176
Détails du profil
Informations forums :
Inscription : août 2007
Messages : 176
Points : 172
Points : 172
Ou alors avec des FULL OUTER JOIN(mais il faut tester au niveau des performances)
Code :
1
2
3
4
5
 
SELECT T1.KEY, NVL(T1.DATA,T2.DATA)
FROM TABLE1 T1
FULL OUTER JOIN TABLE2 T2
ON T1.KEY = T2.KEY
En gros, tu vas prendre toutes les lignes de ta table 1 et de ta table 2, et tu vas les associer qu'elles existent ou pas d'un côté comme de l'autre, et comme dans le cas où elles existent des 2 côtés tu privilégies ta table 1, on utilise l'ordre NVL dans le sens Si 1 NON NULL prendre 1, sinon prendre 2
Loyd1974 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/10/2007, 15h50   #4
Membre Expert
 
Homme
Consultant J2EE
Inscription : octobre 2007
Messages : 889
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Consultant J2EE

Informations forums :
Inscription : octobre 2007
Messages : 889
Points : 1 364
Points : 1 364
Citation:
Envoyé par Loyd1974 Voir le message
Tu peux faire :
Code :
1
2
3
4
5
6
7
8
9
10
SELECT ...
FROM TABLE1 T1
WHERE ...
UNION ALL
SELECT ...
FROM TABLE2 T2
WHERE ...
AND NOT EXISTS (SELECT 1 FROM TABLE1 T1 WHERE T1.KEY = T2.KEY)
...
Si tu n'as pas de doublon au sein de tes 2 tables (c'est à dire que ta clef est vraiment unique au sein de chaque table), tu économises le coût du sort unique du UNION (remplacé par un UNION ALL) qui pourrait compenser un peu le cout de la recherche NOT EXISTS


Waahouuh je suis impressionné niveau performance, car un collegue a fait un truc qui ressemblait un peu sur une autre requete et ca prends pratiquement 30 secondes la requete!!!

un ptit bout de code java de ma dao:

String sqlQuery = FROM_BDU + "WHERE phy.cprn = adr.cprn " +
"AND adr.cprn = prn.cprn " +
"AND phy.cprn NOT IN (SELECT cprn FROM irccttr) " +
"AND UPPER(phy.lnompatprn) LIKE '%" + LastName.toUpperCase() + "%' " +
"AND UPPER(phy.lpreprn) LIKE '%" + FirstName.toUpperCase() + "%' " +
"ORDER BY phy.lnompatprn ";


Lui c'etait avec NOT IN, et pas exists, comment ca se fait que sa requete soit aussi longue par rapport a celle que tu m'as donné ? C'est quoi globalement la difference je comprends pas trop ^^

En tout cas merci ca fait ce que je voulais
HerQuLe est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/10/2007, 16h22   #5
Membre actif
 
Avatar de Loyd1974
 
Inscription : août 2007
Messages : 176
Détails du profil
Informations forums :
Inscription : août 2007
Messages : 176
Points : 172
Points : 172
NOT IN est moins performant que le NOT EXISTS, une recherche sur google te donnera certainement plus de précision là dessus, mais en gros, le NOT IN empêche l'utilisation d'index si celui-ci existe. Dans ton cas, si tu as un index sur le champ KEY de ta table 2, celui-ci n'est pas utilisé avec un NOT IN,mais le NOT EXISTS le prend en compte

Est-ce que tu as essayé avec le FULL OUTER JOIN ? Suivant ton SI, cela pourrait être encore plus rapide ?
Loyd1974 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/10/2007, 18h26   #6
Membre Expert
 
Homme
Consultant J2EE
Inscription : octobre 2007
Messages : 889
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Consultant J2EE

Informations forums :
Inscription : octobre 2007
Messages : 889
Points : 1 364
Points : 1 364
J'ai envi de dire la flemme de tester, 0.2sec contre 30sec ca me convient

merci bien hihi
HerQuLe 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 22h27.


 
 
 
 
Partenaires

Hébergement Web