Bourinho Posté 16 Juillet 2006 Posté 16 Juillet 2006 (modifié) Salut, Mon problème est le suivant : J'ai deux tables SQL table1 et table2. La table1 contient tous les codes INSEE des villes que je souhaite enregistrer ainsi que les noms de ces memes villes. La table2 contient une correspondance entre le code INSEE et le code postal mais cette correspondance est incomplete... Si je fais une jointure entre ces deux tables, je perds des données de la table1... Alors, ce que je voudrais pouvoir faire, c'est insérer les codes postaux dans ma table1 à partir de la table2... sans perdre les données de la table1 (si la correspondance n'est pas disponible dans la table2, je mets le code postal à NULL) Si je fais un jointure, ça ne fonctionne pas (je perds les données de la table1) Avec un UPDATE, faudrait que je fasse une boucle sur la table1 (36684 entrées...)...enfin, je dis "faudrait", mais c'est ce que mes connaissances de MySQL me disent Enfin bref, j'y arrive pas! Si je n'ai pas été assez clair, n'hésitez pas à me le faire savoir! Par avance, merci! PS : Je crois avoir trouver une piste avec la jointure externe!!! Modifié 16 Juillet 2006 par Bourinho
michmuch51 Posté 16 Juillet 2006 Posté 16 Juillet 2006 Pour ma part je t'avoue que quand je veux manipuler des tables entières, je me fais un petit script en php qui ecrit exactement la commande mysql que je souhaite en faisant une boucle, c'est assez rapide et ca te permet de ballader tes données où tu veux dans le sens que tu veux.
Vincent Posté 16 Juillet 2006 Posté 16 Juillet 2006 c'est possible de rendre une jointure externe facultative. plus d'informations sur cette page LE SQL de A à Z : 3e partie - les jointures regarde l'exemple 13, c'est tout a fait ton cas. il faut utiliser LEFT OUTER JOIN ou RIGHT OUTER JOIN.
Bourinho Posté 17 Juillet 2006 Auteur Posté 17 Juillet 2006 (modifié) Bonjour à tous, Merci pour vos reponses... Mais il y a un truc qui me chagrine... une requete avec LEFT OUTER JOIN met beaucoup plus de temps qu'une requete avec une jointure naturelle!!! Alors qu'il n'y a pas tant de différences que ça...enfin dans mon cas... Avec une jointure naturelle, la requete nécessite quelques secondes en étant large... Avec la jointure externe, elle met plus d'une heure! Alors que cette jointure ne me donne que 11 entrées supplémentaires par rapport à la jointure naturelle!!! (sur plus de 36.000) Vous avez une idée d'ou cela peut venir? A+ Modifié 17 Juillet 2006 par Bourinho
Jeromnimo Posté 17 Juillet 2006 Posté 17 Juillet 2006 Essaie avec un INNER JOIN, dans ton cas normalement ca devrait fonctionner... (par contre mets bien ta table complete a gauche et l'autre à droite) A priori tu n'as pas besoin de LEFT OUTER JOIN dans ton cas...
Vincent Posté 17 Juillet 2006 Posté 17 Juillet 2006 Essaie avec un INNER JOIN, dans ton cas normalement ca devrait fonctionner...(par contre mets bien ta table complete a gauche et l'autre à droite) A priori tu n'as pas besoin de LEFT OUTER JOIN dans ton cas... Je suis pas d'accord, s'il utilise INNER JOIN, les enregistrements dont le code postal sera à NULL vont sauter... Maintenant, la table complete a gauche oui, avec LEFT OUTER JOIN (sinon a droite avec RIGHT OUTER JOIN) Après Bourinho, si tu as 11 enregistrements problèmatique sur + de 36 000, est-ce que çà ne vaut pas le coup de faire une recherche pour completer la base de donnée au lieu de se compliquer la vie avec des jointures externes?
MarvinLeRouge Posté 17 Juillet 2006 Posté 17 Juillet 2006 Je suis pas d'accord, s'il utilise INNER JOIN, les enregistrements dont le code postal sera à NULL vont sauter...Maintenant, la table complete a gauche oui, avec LEFT OUTER JOIN (sinon a droite avec RIGHT OUTER JOIN) +1 pour les enregistrements qui vont sauter Après Bourinho, si tu as 11 enregistrements problèmatique sur + de 36 000, est-ce que çà ne vaut pas le coup de faire une recherche pour completer la base de donnée au lieu de se compliquer la vie avec des jointures externes? Ou de faire un inner join, puis de récupérer les autres dans une 2ème requète avec un where, ou un autre truc du genre : un chouilla plus compliqué, mais potentiellement plus rentable.
Bourinho Posté 17 Juillet 2006 Auteur Posté 17 Juillet 2006 (modifié) Salut à tous, +1 pour les enregistrements qui vont sauterOu de faire un inner join, puis de récupérer les autres dans une 2ème requète avec un where, ou un autre truc du genre : un chouilla plus compliqué, mais potentiellement plus rentable. J'ai essayé de faire ça en deux requêtes... mais la seconde, je l'ai faite avec un "where" ou j'ai casé un "IS NOT EXIST" et ça rend le processus encore plus lent! Et sinon, quant à faire cela à la main, je dois vous avouer que c'était la première fois que j'utilisais une jointure externe, donc je ne pouvais pas savoir que cela prendrait autant de temps . Mais, la prochaine fois, je me poserai la question de savoir si j'ai un film à matter... Si c'est le cas, je laisse le PC chauffer pendant le OUTER JOIN, sinon je le fais à la main Encore merci, A+ Modifié 17 Juillet 2006 par Bourinho
Jeromnimo Posté 18 Juillet 2006 Posté 18 Juillet 2006 Autant pour moi, la chaleur commence à me monter au cerveau, ça va pas bien des fois :-P Par contre as-tu bien verifié tes index dans tes tables ? Il faut obligatoirement qu'ils soient indexés pour que la jointure soit rapide, sinon MySQL a du mal a gérer... SI tu as PHPmyAdmin ou une console sql, essaye de faire un explain de ta requete avec le left outer join (ou right outer join) et dis nous ce que tu as dans les champs type.
Bourinho Posté 19 Juillet 2006 Auteur Posté 19 Juillet 2006 (modifié) Salut, J'ai suivi ton conseil pour ce qui est du "EXPLAIN de ma requête". Je lui ai mis ça: EXPLAIN SELECT villesfinales.CodeINSEE AS CodeINSEE,villesfinales.Article AS Article,villesfinales.nom AS Nom,villesfinales.NomComplet AS NomComplet,villesfinales.Departement AS Departement,villesfinales.NumDepartement AS NumDepartement,villesfinales.CodeRegion AS CodeRegion,villesfinales.CodePostal AS CodePostal,villestcd.Latitude AS Latitude,villestcd.Longitude AS LongitudeFROM villesfinales LEFT OUTER JOIN villesTCD ON (villesfinales.NomComplet=villestcd.Nom AND villesfinales.CodeRegion=villestcd.CodeRegion) Résultat : id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE villesfinales ALL NULL NULL NULL NULL 36726 1 SIMPLE villesTCD ALL NULL NULL NULL NULL 68003 Ca ne ressemble pas à une optimisation de table!!! Ensuite, tu soulèves une piste qui me parait fort intéressant...celle des index!!! Ne sachant pas l'utilité de cela, j'en ai mis nulle part... (A part une clé primaire sur les Codes INSEE...car ils sont censés être uniques!). Alors, je pense qu'en effet, mes tables sont loins d'être optimisées, mais je ne sais pas du tout quoi mettre en index ne sachant pas ce que cela change pour MySQL quand il tombe dessus! Par avance, merci! PS : J'ai lu que cela permettait de créer un arbre équilibré pour accélérer les recherches... Ca doit donc être bien utile dans mon cas en effet... (Pour info, j'ai mis un index sur le Nom des villes mais pas sur CodeRegion (seulement 24 possibilités...). Je vous en dirai plus demain car je vais lancer cette requête demain pour la journée! En fait, je viens de la lancer... et je comprends l'intérêt des index désormais!!!! ça a mis 6 secondes au lieu de plus de 3 heures!!! Merci à tous! (je crois que je vais m'intéresser de prêt à ces index!!!!) Modifié 19 Juillet 2006 par Bourinho
Jeromnimo Posté 19 Juillet 2006 Posté 19 Juillet 2006 Tant meiux si la piste a pu t'aiguiller comme il faut :-) En ce qui concerne l'interpretation du EXPLAIN, il y le champ marqué ALL dans ton explain qui signifie que ce n'est pas optimisé du tout (il va falloir parcourir l'nesemble de la table a joindre pour chaque ligne de la première table (d'ou le temps prohibitif) L'idéal est d'avoir ref lorsque tu fais une jointure. Sinon, en ce qui concerne les champs à indexer, les clefs primaires le sont automatiquement si tu les a définies comme PRIMARY KEY, et il faut créer un index sur les colonnes référantes, c'est à dira dans ton cas : * villesfinales.NomComplet * villestcd.Nom * villesfinales.CodeRegion * villestcd.CodeRegion
Bourinho Posté 19 Juillet 2006 Auteur Posté 19 Juillet 2006 (modifié) Salut, J'ai lu que les index n'était pas efficace s'il y avait peu de possibilités pour une valeur (dans mon cas, je prendrais l'exemple de CodeRegion : 24 possibilités). C'est "pas efficace" (=perte de temps) ou "moins efficace" (=gain de temps moindre que pour un nombre de possibilités plus élevé!). Je penche pour la seconde solution mais c'était juste pour chipoter... Merci Modifié 19 Juillet 2006 par Bourinho
Jeromnimo Posté 19 Juillet 2006 Posté 19 Juillet 2006 Je pense que le problème est légèrement différent du fait que tu fais une jointure avec une autre table. De toute façon, il faut indexer le code région pour tes ~37 000 valeurs dans ta table de ville, c'est la que sera la différence ;-) Au lieu de parcourir la table, il se servira de l'index :-P
Bourinho Posté 19 Juillet 2006 Auteur Posté 19 Juillet 2006 Et dire qu'avant j'attendais plus de 3 heures à chaque fois que je lançais ce genre de requête... j'en rigole maintenant!!! Je pense que je vais vraiment m'intéresser aux index, car cela ne semble pas très sorcier de bien les choisir et cela permet de soulager grandement le serveur... A+ et encore merci pour tous ces renseignements!
Sujets conseillés
Veuillez vous connecter pour commenter
Vous pourrez laisser un commentaire après vous êtes connecté.
Connectez-vous maintenant