Précédent   Forum des professionnels en informatique > Bases de données > MySQL
MySQL Forum d'entraide MySQL. Avant de poster -> FAQ MySQL, Tutoriels MySQL
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 06/01/2011, 17h16   #1
Membre actif
 
Avatar de bigsister
 
Homme OLE MAIN()
Développeur Web
Inscription : octobre 2002
Messages : 296
Détails du profil
Informations personnelles :
Nom : Homme OLE MAIN()
Localisation : France

Informations professionnelles :
Activité : Développeur Web
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : octobre 2002
Messages : 296
Points : 191
Points : 191
Par défaut LIMITER UN LEFT JOIN à un seul résultat

Bonjour à tous,

Voilà mon problème :
J'ai une table A avec 1 000 lignes.
Ma table A n'a qu'un champ "id"

J'ai une table B avec 1 000 000 de lignes.
Ma table B a 2 champs "id" et "date"

à 1 enregistrement de A peuvent correspondre N enregistrements de B.

Je souhaiterais simplement afficher dans une page tous mes A.id, suivis d'une seule date trouvée dans B (la première trouvée):
Code :
1
2
3
SELECT A.id, B.date
FROM A LEFT JOIN B ON A.id = B.id
GROUP BY A.id
Le problème c'est qu'en faisant cela, étant donné que pour un id dans A je peux avoir une correspondance avec 50 000 enregistrements dans B... ma requête rame...
J'ai pas mal cherché mais je n'ai pas trouvé de solution pour le moment...

Quelqu'un aurait une idée ?
bigsister est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/01/2011, 17h20   #2
Membre Expert
 
Inscription : mars 2005
Messages : 1 565
Détails du profil
Informations personnelles :
Âge : 29
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : mars 2005
Messages : 1 565
Points : 2 178
Points : 2 178
"La première trouvée" implique forcément un ordre donc "première trouvée" par rapport à quoi ?

Sinon la solution est dans l'utilisation d'un group by : http://sqlpro.developpez.com/cours/sqlaz/ensembles/

Et deuxième remarque, si la date jointe n'a pas d'importance, pourquoi la ramener ?
vmolines est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/01/2011, 17h54   #3
Membre actif
 
Avatar de bigsister
 
Homme OLE MAIN()
Développeur Web
Inscription : octobre 2002
Messages : 296
Détails du profil
Informations personnelles :
Nom : Homme OLE MAIN()
Localisation : France

Informations professionnelles :
Activité : Développeur Web
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : octobre 2002
Messages : 296
Points : 191
Points : 191
La date a de l'importance mais je ne récupère que la première trouvée dans ma table car en principe c'est la plus ancienne (la première insérée) et c'est ça qui m'intéresse.
Le group by réduit le résultat final, mais il n'empêche pas MySQL de parcourir tous les enregistrements...
Le lien que tu m'as donné est intéressant mais il me semble déjà avoir envisagé tout ça
bigsister est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/01/2011, 18h20   #4
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 10 980
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 10 980
Points : 18 224
Points : 18 224
Envoyer un message via MSN à CinePhil
La plus ancienne date => MIN(la_colonne_date)
Avec le GROUP BY indiqué par vmolines, tu devrais t'en sortir...
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/01/2011, 10h00   #5
Membre Expert
 
Inscription : mars 2005
Messages : 1 565
Détails du profil
Informations personnelles :
Âge : 29
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : mars 2005
Messages : 1 565
Points : 2 178
Points : 2 178
Citation:
Envoyé par bigsister Voir le message
La date a de l'importance mais je ne récupère que la première trouvée dans ma table car en principe c'est la plus ancienne (la première insérée) et c'est ça qui m'intéresse.
Le group by réduit le résultat final, mais il n'empêche pas MySQL de parcourir tous les enregistrements...
Le lien que tu m'as donné est intéressant mais il me semble déjà avoir envisagé tout ça
Il est évident que si vous allez chercher des données dans la table jointe, les lignes seront lues. Vous ne pouvez dire que vous souhaitez ces données et en même temps vouloir que le SGBD ne les lise pas...

Vous pouvez optimiser ces lectures en indexant les colonnes utilisées dans le group by notamment. Pour plus de détail, référez vous à la doc de MySQL : http://dev.mysql.com/doc/refman/5.1/...imization.html
vmolines est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/01/2011, 10h35   #6
Membre actif
 
Avatar de bigsister
 
Homme OLE MAIN()
Développeur Web
Inscription : octobre 2002
Messages : 296
Détails du profil
Informations personnelles :
Nom : Homme OLE MAIN()
Localisation : France

Informations professionnelles :
Activité : Développeur Web
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : octobre 2002
Messages : 296
Points : 191
Points : 191
Citation:
Il est évident que si vous allez chercher des données dans la table jointe, les lignes seront lues. Vous ne pouvez dire que vous souhaitez ces données et en même temps vouloir que le SGBD ne les lise pas...
Je veux bien qu'il fasse ma jointure mais qu'il se limite au premier résultat dans ma table B...

Je n'ai toujours pas trouvé de solution. Le group by me renverra bien ce que je veux mais le problème c'est que MySQL va lire toutes mes correspondances dans B...
bigsister est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/01/2011, 10h47   #7
Membre Expert
 
Inscription : mars 2005
Messages : 1 565
Détails du profil
Informations personnelles :
Âge : 29
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : mars 2005
Messages : 1 565
Points : 2 178
Points : 2 178
Si vous suivez les conseils d'optimisation de la clause Group By, un index pourra être utilisé et limiter les lectures au minimum.

Pour optimiser vos requêtes il va falloir apprendre à utiliser la commande Explain qui permet de voir le plan d'exécution utilisé par le SGBD pour traiter votre requête : http://dev.mysql.com/doc/refman/5.1/...g-explain.html
vmolines est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/01/2011, 11h21   #8
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 10 980
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 10 980
Points : 18 224
Points : 18 224
Envoyer un message via MSN à CinePhil
Citation:
Envoyé par bigsister Voir le message
Je veux bien qu'il fasse ma jointure mais qu'il se limite au premier résultat dans ma table B...

Je n'ai toujours pas trouvé de solution. Le group by me renverra bien ce que je veux mais le problème c'est que MySQL va lire toutes mes correspondances dans B...
Pourquoi t'inquiètes-tu pour ça ?
1 million de lignes, ce n'est pas encore énorme pour un SGBD. J'ai travaillé avec des tables de plusieurs dizaines de millions de lignes en jointure avec un temps de réponse tout à fait satisfaisant.

Si tu mets un index sur la colonne de date, il va utiliser l'index pour trouver très rapidement la date mini.
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/01/2011, 13h56   #9
Membre actif
 
Avatar de bigsister
 
Homme OLE MAIN()
Développeur Web
Inscription : octobre 2002
Messages : 296
Détails du profil
Informations personnelles :
Nom : Homme OLE MAIN()
Localisation : France

Informations professionnelles :
Activité : Développeur Web
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : octobre 2002
Messages : 296
Points : 191
Points : 191
Citation:
Envoyé par CinePhil Voir le message
Pourquoi t'inquiètes-tu pour ça ?
1 million de lignes, ce n'est pas encore énorme pour un SGBD. J'ai travaillé avec des tables de plusieurs dizaines de millions de lignes en jointure avec un temps de réponse tout à fait satisfaisant.

Si tu mets un index sur la colonne de date, il va utiliser l'index pour trouver très rapidement la date mini.
En théorie oui, mais en pratique ma page met 2 min à s'afficher...
bigsister est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/01/2011, 16h47   #10
Membre actif
 
Avatar de bigsister
 
Homme OLE MAIN()
Développeur Web
Inscription : octobre 2002
Messages : 296
Détails du profil
Informations personnelles :
Nom : Homme OLE MAIN()
Localisation : France

Informations professionnelles :
Activité : Développeur Web
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : octobre 2002
Messages : 296
Points : 191
Points : 191
Apparemment c'est un problème récurrent que je suis loin d'être le seul à rencontrer... Ca semble basique et pourtant... pour résumer : comment limiter la selection à un seul enregistrement à droite quand on utilise un LEFT JOIN...

Si ça peut aider à me comprendre :
J'ai 1 000 clients qui ont chacun 1 000 connexions d'enregistrées.
Je veux afficher un tableau avec les 1 000 clients et pour chacun la date de la première connexion... sachant que je n'ai pas d'index sur mon champs date (je ne peux pas) mais qu'à priori la première ligne que MySQL trouvera pour chaque client sera la bonne...
bigsister est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/01/2011, 17h07   #11
Membre Expert
 
Inscription : mars 2005
Messages : 1 565
Détails du profil
Informations personnelles :
Âge : 29
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : mars 2005
Messages : 1 565
Points : 2 178
Points : 2 178
GROUP BY sur les colonnes de la table de gauche et une fonction d'agrégat sur la colonne de la table de droite...
vmolines est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/01/2011, 17h10   #12
Membre actif
 
Avatar de bigsister
 
Homme OLE MAIN()
Développeur Web
Inscription : octobre 2002
Messages : 296
Détails du profil
Informations personnelles :
Nom : Homme OLE MAIN()
Localisation : France

Informations professionnelles :
Activité : Développeur Web
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : octobre 2002
Messages : 296
Points : 191
Points : 191
Citation:
Envoyé par vmolines Voir le message
GROUP BY sur les colonnes de la table de gauche et une fonction d'agrégat sur la colonne de droite...
Si j'ai une fonction d'agrégat sur la colonne de droite c'est bien qu'il doit parcourir tous les enregistrements de droite pour faire l'agrégation (MAX, MIN etc..)... non ?
bigsister est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/01/2011, 17h15   #13
Membre Expert
 
Inscription : mars 2005
Messages : 1 565
Détails du profil
Informations personnelles :
Âge : 29
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : mars 2005
Messages : 1 565
Points : 2 178
Points : 2 178
Et moi aussi j'ai du mal à me faire comprendre.

Comment le SGBD peut dire que c'est la première connexion s'il ne compare pas toutes les dates de connexion ?

Deuxio, dire qu'on ne peut pas mettre un index quand on a une requête qui rame à cause de ce manque, c'est juste stupide. Alors peut être que vous ne pouvez pas à votre échelle mais ça reste stupide
vmolines est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/01/2011, 17h18   #14
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 10 980
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 10 980
Points : 18 224
Points : 18 224
Envoyer un message via MSN à CinePhil
Citation:
Envoyé par bigsister Voir le message
sachant que je n'ai pas d'index sur mon champs date (je ne peux pas)
Ben t'es mal barré !
Pourquoi tu ne peux pas ?
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/01/2011, 17h22   #15
Membre Expert
 
Inscription : mars 2005
Messages : 1 565
Détails du profil
Informations personnelles :
Âge : 29
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : mars 2005
Messages : 1 565
Points : 2 178
Points : 2 178
Dans mon petit parcours, j'ai été surpris de la quantité d'arguments qu'on a pu me donner pour mal faire les choses .
vmolines est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/01/2011, 10h14   #16
Membre actif
 
Avatar de bigsister
 
Homme OLE MAIN()
Développeur Web
Inscription : octobre 2002
Messages : 296
Détails du profil
Informations personnelles :
Nom : Homme OLE MAIN()
Localisation : France

Informations professionnelles :
Activité : Développeur Web
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : octobre 2002
Messages : 296
Points : 191
Points : 191
vmolines c'est pas très sympa... je ne suis pas un débutant non plus. Disons qu'en l'état actuel de mon système, rajouter un index sur des millions d'enregistrements à chaud présente un risque de crash de MySQL (J'en ai déjà fait l'expérience)...

Donc OK, ne pas avoir d'index sur un champ de recherche c'est un peu dommage mais pour l'instant je ne peux pas mieux faire sans interrompre le service... d'autant que c'est la seule requête qui nécessite vraiment cet index (donc pas critique à priori).
bigsister est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/01/2011, 11h07   #17
Membre Expert
 
Inscription : mars 2005
Messages : 1 565
Détails du profil
Informations personnelles :
Âge : 29
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : mars 2005
Messages : 1 565
Points : 2 178
Points : 2 178
Citation:
Envoyé par bigsister Voir le message
vmolines c'est pas très sympa... je ne suis pas un débutant non plus. Disons qu'en l'état actuel de mon système, rajouter un index sur des millions d'enregistrements à chaud présente un risque de crash de MySQL (J'en ai déjà fait l'expérience)...

Donc OK, ne pas avoir d'index sur un champ de recherche c'est un peu dommage mais pour l'instant je ne peux pas mieux faire sans interrompre le service... d'autant que c'est la seule requête qui nécessite vraiment cet index (donc pas critique à priori).
Je ne suis pas là pour être sympa mais pour t'aider dans la résolution de ton problème.

Désolé si les solutions que je propose ne sont pas sympas et si MySQL crashe sur la création d'un index.
vmolines est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/01/2011, 13h08   #18
Membre confirmé
 
Homme Benjamin
Consultant informatique
Inscription : août 2007
Messages : 160
Détails du profil
Informations personnelles :
Nom : Homme Benjamin
Localisation : France, Hauts de Seine (Île de France)

Informations professionnelles :
Activité : Consultant informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : août 2007
Messages : 160
Points : 248
Points : 248
A tout hasard :
Code :
1
2
3
SELECT id, MIN(date)
FROM B
GROUP BY id
Tu n'as pas besoin de la jointure dans le cas que tu exposes. A priori, pour 1,000,000 d'enregistrements, ça devrait aller très vite avec cette requête.
bhamp0 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/01/2011, 13h16   #19
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 10 980
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 10 980
Points : 18 224
Points : 18 224
Envoyer un message via MSN à CinePhil
C'est ce qu'on lui dit depuis le début mais il s'obstine à vouloir éviter que toute la table soit parcourue sans mettre d'index sur la colonne de date, ce qui est impossible pour trouver la date mini de chaque valeur de regroupement.
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/01/2011, 18h06   #20
Membre actif
 
Avatar de bigsister
 
Homme OLE MAIN()
Développeur Web
Inscription : octobre 2002
Messages : 296
Détails du profil
Informations personnelles :
Nom : Homme OLE MAIN()
Localisation : France

Informations professionnelles :
Activité : Développeur Web
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : octobre 2002
Messages : 296
Points : 191
Points : 191
bhamp0 j'ai 2 tables donc sans jointure pas possible

Cinephil, à la base je m'en fous du MIN(date) je veux le premier enregistrement qu'il rencontre dans la table B car je sais que ce sera le MIN.
Je n'utilise justement pas cette fonction MIN pour ne pas parcourir ma table sur un champ qui n'est pas indexé comme tu l'as dis...

Après soit je me fait mal comprendre soit je suis à côté de la plaque sur ce coup là et c'est moi qui ne vous comprends pas... donc je posterai quand j'aurai trouvé.

Merci quand même !
bigsister 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 17h20.


 
 
 
 
Partenaires

Hébergement Web