Page 1 sur 2
JOIN vous avez dit JOIN ?
Posté : 26 avr. 2011, 17:05
par foetus69
Bonjour,
Je cherche à savoir par l'échange, la pédagogie dans quels cas on utilise un JOIN ? A quoi ca sert ? Et pourquoi RIGHT, INNER, etc. ?
Personnellement pour faire une jointure je fais comme ceci :
SELECT id FROM table1, table2 WHERE table1.id = table2.id;
Merci pour vos lights !!!
Tite fée du 69.
Re: JOIN vous avez dit JOIN ?
Posté : 26 avr. 2011, 17:13
par popy
SELECT id FROM table1 INNER JOIN table2 ON (table1.id = table2.id)
C'est beaucoup plus performant, puisque le filtrage se fait avant la récupération de la liste potentielle de résultat, alors que le WHERE se fait après, pour qu'il puisse être testé sur tout le jeu de données.
En gros, si table1 et table2 contiennent chacune 10 ligness, la requete avec JOIN va travailler sur 10 lignes (les 10 de table1 directement associées à celles de table2), alors que l'autre va d'abord compiler une liste de 100 lignes (table1.1 avec table2.1, table1.1 avec table2.2) etc...), puis checker ton where sur chacune d'entre elles.
Pour le reste, RTFM
Re: JOIN vous avez dit JOIN ?
Posté : 27 avr. 2011, 08:10
par xTG
C'est une évolution du langage SQL datant de 1992.
Les jointures comme tu les fait existent bien sûr toujours mais ne sont pas autant optimisées (cf post de
popy).
En gros, il serait temps de se mettre à jour.

Re: JOIN vous avez dit JOIN ?
Posté : 27 avr. 2011, 09:16
par Mazarini
Bonjour,
Je fais partie des attardés du join. Je croyais que c'était des ajouts non standard propre à certains SGBD.
La jointure à l'ancienne bénéficie quand même d'optimisation en fonction des index et des nombres de lignes dans les tables.
J'utilise quand même le nouveau join pour remplacer des "select ... where X not in select ...". Mais à chaque fois j'ai besoin de la doc ou d'exemples.
Ca se fait dans le genre :
SELECT id FROM table1 RIGHT JOIN table2 ON (table1.id = table2.id) where table2.id = NULL
Re: JOIN vous avez dit JOIN ?
Posté : 27 avr. 2011, 17:30
par ouckileou
C'est aussi bien, surtout pour de grosses requetes, de separer les jointures et le filtrage. C'est tout de meme plus lisible.
Re: JOIN vous avez dit JOIN ?
Posté : 27 avr. 2011, 17:47
par popy
La jointure à l'ancienne bénéficie quand même d'optimisation en fonction des index et des nombres de lignes dans les tables.
Euh... t'as conscience que les jointures exploitent les index de façon encore plus optimisée, puisque ce sera pour mettre en relation x lignes de la table2 avec les x lignes de la table1, au lieu d'être utilisés pour exclure les (x²-x) lignes qui ne se correspondent pas ?
Re: JOIN vous avez dit JOIN ?
Posté : 28 avr. 2011, 09:20
par Mazarini
Bonjour,
Les SGBD ne calculent pas forcément la jointure avec les x2-x cas. Ils peuvent faire une lecture synchronisée des 2 tables pour rapprocher les enregistrements. Si une des 2 tables est petite, ils peuvent la charger en mémoire pour faire la recherche directement à chaque enregistrement.
Un SGBD comme DB2 optimise les requêtes lors d'une phase de pré-compilation des programmes. Cela implique d'ailleurs de recompiler les programmes en cas de grosses modifications de la base en terme de volume pour re-optimiser les programmes.
L'avantage du join est de permettre au développeur de guider le SGBD dans sa méthode d'accès. Après reste à savoir qui est le meilleur entre le développeur et le SGBD. Un bon développeur est normalement meilleurs, mais tous ne sont pas très bon... ou s'en foutent.
L'utilisation du sélect n'est pas si catastrophique que tu sembles le penser, mais j'ai bien noté qu'il faut que je me mette au join (surtout dans les cas "long"). Un triste constat conduit souvent à préférer descendre une table dans un fichier, traiter les données et recharger la table dès que le nombre de modifications est important.
Re: JOIN vous avez dit JOIN ?
Posté : 28 avr. 2011, 10:19
par foetus69
Bonjour à tous,
Merci pour vos explications (c'est plus clair) et contente de voir que ça suscite des réactions
@xtg : Ca date de 92 ? Faudrait en effet que je me mette à jour, mais j'utilise ce qu'on m'a appris. Y a pas un site des dernières bonnes pratiques ? Tu fais ta veille où et comment ? Je vais ouvrir un autre topic pour ne pas se mélanger les pinceaux.
Dernière chose sur le JOIN :
C'est quoi l'histoire des LEFT, RIGHT etc ?
J'ai vu aussi cette syntaxe :
SELECT mc.* FROM table1 mc INNER JOIN table2 t2 ON mc.id_card=t2.id
On crée un "mc" fictif pour s'appuyer dessus, c'est bien ça ? Car le "mc" et le "t2" je ne les retrouve nulle part ailleurs...
Bonne journée sous la grisaille ^^
Re: JOIN vous avez dit JOIN ?
Posté : 28 avr. 2011, 10:36
par popy
@xtg : Ca date de 92 ? Faudrait en effet que je me mette à jour, mais j'utilise ce qu'on m'a appris.
La veille techno fait partie de notre travail de développeur...
SELECT mc.* FROM table1 mc INNER JOIN table2 t2 ON mc.id_card=t2.id
C'est juste un alias, c'est vieux comme le monde.
@Mazarini : bien heureusement les optimiseurs de requêtes des SGBD sont suffisamment bien foutus pour limiter la casse, pour ce genre de jointures. Mais une belle jointure bien faite (qui nécessite d'y réfléchir UNE fois lorsqu'on l'écrit) épargne cette tâche au SGBD, sans quoi il devrait la faire à chaque fois que la requête est exécutée.
Re: JOIN vous avez dit JOIN ?
Posté : 28 avr. 2011, 11:04
par Mazarini
Bonjour,
En fait (si j'ai bien compris) le left et le right permettent effectivement d'obtenir les lignes sans correspondance à droite ou à gauche avec des colonnes à null. Il existe aussi un moyen d'avoir les absents des 2 cotés.
Pour la défense de mon ignorance, dans un article de 2004 :
Oracle à dû attendre la version 9 alors que MySQL la version 3.23.17 pour le « INNER JOIN »! et MySQL 4.0.11 pour le « UNION » et « CROSS JOIN » (mise à jour 2004). Rien ne vaut alors l'essai erreur. Pour leur part, PostGreSQL se limite au « LEFT », « RIGHT » alors que DB2, bien que très puissant, au « LEFT ».
Ca relativise mon manque de connaissance par rapport à 1992 :p. J'ai du utiliser le right une unique fois en 2001 pour trouver les absents.
J'en retiens qu'au niveau des performance il n'y a pas vraiment de gain (optimisation par le SGBD), mais au niveau de la lisibilité ca apporte un plus certain en séparant l'aspect jointure et l'aspect sélection dans la jointure.
Edit : En général j'écris mes requêtes pour quelles soient lisible sans trop me préoccupé des performances sauf à avoir des problèmes de charge. C'est plus au niveau de la conception de la base que se fait le travail d'optimisation avec le choix des index et l'ordre des colonnes dans les index pour mettre les plus discriminantes en premier. Mon pire cas est une requête demandant 2 heures avant de sortir la première ligne, mais il y avait 1000000 lignes de résultat avec beaucoup de tables et des jointures impliquant des comparaison de dates en plus des identifiants.
Re: JOIN vous avez dit JOIN ?
Posté : 28 avr. 2011, 11:52
par popy
J'en retiens qu'au niveau des performance il n'y a pas vraiment de gain (optimisation par le SGBD), mais au niveau de la lisibilité ca apporte un plus certain en séparant l'aspect jointure et l'aspect sélection dans la jointure.
D'ou tu tiens ça ? Des chiffres ? Perso, par curiosité j'ai fait un test comparatif : avec jointure ça prend 10x moins de temps que sans, avec une jointure sur un varchar en clef primaire.
Re: JOIN vous avez dit JOIN ?
Posté : 28 avr. 2011, 15:15
par Mazarini
Source :
http://trucsweb.com/ASP/trucs.asp?no=104&type=7
2. TOUJOURS utiliser le mot clé « JOIN » bien qu'il ne soit pas indispensable. C'est une erreur fréquente que de préciser une jointure directement dans la clause « WHERE ». Bien qu'il n'y ait aucune différence au niveau de la performance et que le résultat soit généralement le même (pas toujours alors!) il est bon de bien organiser notre requête et de bien identifier les critères de recherche des combinaisons de tables.
Je reconnais que l'on entend plus facilement ce que l'on veut entendre...
Je pense que tes tests proviennent de mysql qui n'est peut être pas un modèle d'optimisation ou que ta base à besoin d'une réorganisation.
D'après ce que je sais, avec DB2, une étape "bind" permet de calculer les optimisations des requêtes d'un programme une fois pour toutes. Du coté d'Oracle, une réorganisation permet aussi de connaitre le coté discriminant des colonnes et le nombre d'enregistrements des tables ce qui aide à l'optimisation. Il est conseillé de refaire le bind des programmes ou la réorg lorsque la base atteint sa taille de croisière pour relancer les optimisations.
Re: JOIN vous avez dit JOIN ?
Posté : 28 avr. 2011, 15:27
par foetus69
Bon voilà, pour le coup, j'ai essayé ceci un cas qui me parraissait simple et sympa de prime abord mais pourtant :
J'ai créé 3 tables : table1, table2, table3.
Le but : afficher les enregistrements de table3 si je retrouve la clef étrangère certains champs de table1 ou table2...
Exemple :
dans la table 1 nom = toto (clef primaire car y a qu'un toto, le vrai, le seul)
dans la table 2 commentaires = toto a bien mangé ce midi (une occurence trouvée)
dans la table 3 nom = toto (clef étrangère de table 1)
Comme je trouve des choses en rapport avec "toto" dans l'une des 2 tables, c'est ok j'affiche les infos de la table3 relatives à toto.
Je suis sur cet exo depuis ce midi et m'arrache les cheveux avec les alias en prime

Re: JOIN vous avez dit JOIN ?
Posté : 28 avr. 2011, 16:50
par foetus69
re re re bonjour Messieurs,
J'ai fait ceci mais pour le coup ne comprends pas pourquoi ça m'affiche "toto"
$query = "SELECT t3.* FROM table3 t3 LEFT JOIN table2 t2 ON t3.nom = t2.champ2";
car t2.champ2 ne comporte pas "toto" mais "tt" à la ligne 2.
table1
nom
titi
toto
tata
tutu
table2
champ1 | champ2 | champ3
azerty | tutu | Je suis ravi
qui suis-je ? | il en va de la vie de tt | oh oh oh
table3
prenom | nom | age
jean-michel | toto | 18
En resaisissant toto à la place de tt j'ai fait ceci et pensais que ca marcherait
$query = "SELECT t3.* FROM table3 t3 RIGHT OUTER JOIN table2 t2 ON t3.nom LIKE '%t2.champ2'";
mais non, même pas

Re: JOIN vous avez dit JOIN ?
Posté : 29 avr. 2011, 08:08
par xTG
LEFT JOIN donc c'est normal.
Il prend ce qu'il y a dans t3 et il recherche une correspondance dans t2, mais dans tous les cas tu auras les enregistrements de t3 même s'il n'y a pas de correspondances dans t2.
Si tu veux une égalité sûre et certaine il faut utiliser INNER JOIN.