erreur dans ma requête ?

Eléphanteau du PHP | 17 Messages

14 avr. 2006, 09:17

Bonjour à tous

Cette requête fonctionne correctement sur mon ordinateur...

Code : Tout sélectionner

"SELECT c.titre, c.ref, c.detail_instru, c.prix, c.id_auteur1, c.id_auteur2,i.instrument, au_1.nom AS nom1, au_1.prenom AS prenom1, au_2.nom AS nom2, au_2.prenom AS prenom2 FROM catalogue AS c, Instruments AS i, Auteurs AS au_1, Auteurs AS au_2 WHERE c.id_instrument = i.id AND au_1.id = c.id_auteur1 AND au_2.id = c.id_auteur2 ORDER BY ref DESC LIMIT 10;"
... mais sur le serveur de online il me renvoit le message d'erreur suivant :

Erreur dans l'execution de la requete 'SELECT c.titre, c.ref, c.detail_instru, c.prix, c.id_auteur1, c.id_auteur2,i.instrument, au_1.nom AS nom1, au_1.prenom AS prenom1, au_2.nom AS nom2, au_2.prenom AS prenom2 FROM catalogue AS c, Instruments AS i, Auteurs AS au_1, Auteurs AS au_2 WHERE c.id_instrument = 0 AND c.id_instrument = i.id AND au_1.id = c.id_auteur1 AND au_2.id = c.id_auteur2 ORDER BY ref DESC'. Message de MySQL : The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET SQL_MAX_JOIN_SIZE=# if the SELECT is okay

Quelqu'un aurait-il une idée pour corriger l'erreur ?

Merci

Administrateur PHPfrance
Administrateur PHPfrance | 977 Messages

14 avr. 2006, 09:28

pff perso je trouve ses requetes illisibles ! faites les jointures avec inner join, left join et right join ! c'est plus optimisé et plus facile en lecture !

ca donnerai quelques choses comme ca

Code : Tout sélectionner

SELECT catalogue.titre, catalogue.ref, catalogue.detail_instru, catalogue.prix, catalogue.id_auteur1, catalogue.id_auteur2, Instruments.instrument, au1.nom AS nom1, au1.prenom AS prenom1, au2.nom AS nom2, au2.prenom AS prenom2 FROM catalogue INNER JOIN Instruments ON catalogue.id_instrument=Instruments.id LEFT JOIN Auteurs as au1 ON Instruments.id_auteur1 = au1.id LEFT JOIN Auteurs as au2 ON Instruments.id_auteur2 = au2.id ORDER BY ref DESC LIMIT 10;
pro : http://www.ohweb.fr -> studio de développement en PHP, expertise en e-commerce, certifié PrestaShop
perso : http://www.olecorre.com -> un dico de termes informatiques

J'ai toujours rêvé d'un ordinateur qui soit aussi facile à utiliser qu'un téléphone. Mon rêve s'est réalisé : je ne sais plus comment utiliser mon téléphone. [Bjarne Stroustrup]

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

14 avr. 2006, 13:13

@Cobaye: C'est bizarre, j'ai toujours préféré utiliser une virgule parce que c'est plus court. (plus lisible pour moi) En revanche, je ne comprends pas ce que tu entends par "plus optimisé". Le manuel nous dit que les deux sont sémantiquement équivalents (INNER JOIN ayant précédence sur la virgule, mais en règle générale en s'en fiche).

@pitav: le message d'erreur dit que ta requête examinerait trop d'enregistrements si elle était exécutée, donc elle est probablement fausse. Ajoute un "c.id_instrument = 123" pour ne récupérer que les enregistrements de l'instrument 123 et voir si le résultat correspond à ce que tu souhaites obtenir.

Administrateur PHPfrance
Administrateur PHPfrance | 977 Messages

14 avr. 2006, 14:23

J'ai écris un tuto sur direction PHP sur le sujet avec deux exécutions de requête avec une jointure.

Quand tu fais une requête multicritère avec plusieurs jointures etc... en lecture pour moi y a pas photo 10 fois plus lisible avec les inner join. En plsu en where comment veux tu faire simplement des left join ?

Si tu veux l'article que j'ai écris envoie moi un message et te l'enverrai
pro : http://www.ohweb.fr -> studio de développement en PHP, expertise en e-commerce, certifié PrestaShop
perso : http://www.olecorre.com -> un dico de termes informatiques

J'ai toujours rêvé d'un ordinateur qui soit aussi facile à utiliser qu'un téléphone. Mon rêve s'est réalisé : je ne sais plus comment utiliser mon téléphone. [Bjarne Stroustrup]

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

14 avr. 2006, 14:55

Loin de moi l'idée de remplacer toutes les jointures par des virgules ! Je disais simplement que dans le cas présent c'était surtout une question de préférence personnelle. Je ne vois aucune raison objective de préférer lNNER JOIN à une virgule, à part dans les cas où la précédence des jointures est important, c'est à dire lorsqu'on joint la troisième table à la première sans utiliser de parenthèses pour exprimer clairement l'ordre des jointures.

Dans ton précédent post tu disais "c'est plus optimisé" mais je pense que tu parlais du confort visuel, pas des performances c'est ça ? Je n'ai pas pris la peine de vérifier sur d'anciennes version, mais sous MySQL 5.0.19 "INNER JOIN", "CROSS JOIN" et "," sont automatiquement remplacés par "JOIN" en interne. (d'après EXPLAIN EXTENDED)

Administrateur PHPfrance
Administrateur PHPfrance | 977 Messages

14 avr. 2006, 15:00

Optimiser en performance aussi !

j'ai mis le tuto dans ma signature, regarde à la fin du tuto !

Enfin l'important c'est d'être à l'aise dans l'une ou l'autre écriture
pro : http://www.ohweb.fr -> studio de développement en PHP, expertise en e-commerce, certifié PrestaShop
perso : http://www.olecorre.com -> un dico de termes informatiques

J'ai toujours rêvé d'un ordinateur qui soit aussi facile à utiliser qu'un téléphone. Mon rêve s'est réalisé : je ne sais plus comment utiliser mon téléphone. [Bjarne Stroustrup]

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

14 avr. 2006, 15:07

Je viens de jeter un œil sur l'article, c'est étrange... Je vais essayer de reproduire cette requête pour en savoir plus, car ça m'intrigue. Si tu as toujours la base de données sous la main, pourrais-tu me donner une estimation de la taille des deux tables et la cardinalité des deux champs stp ?

Eléphanteau du PHP | 17 Messages

14 avr. 2006, 15:11

Je me suis absenté.
J'essaye vos propositions.
Merci pour ces premières explications.
Je vous tiens au courant.

Eléphanteau du PHP | 17 Messages

21 avr. 2006, 10:20

Bonjour à tous
Merci Cobaye pour ton tutu.
Je trouve effectivement plus clair de séparer les jointure de la clause WHERE.

J'ai donc rédiger une nouvelle requête qui fonctionne parfaitement sur mon serveur.

Code : Tout sélectionner

SELECT c.titre, c.ref, c.detail_instru, c.prix, i.instrument, c.id_auteur1, c.id_auteur2, au_1.nom AS nom1, au_2.nom AS nom2 FROM catalogue AS c INNER JOIN Instruments AS i ON c.id_instrument = i.id LEFT JOIN Auteurs AS au_1 ON c.id_auteur1 = au_1.id LEFT JOIN Auteurs AS au_2 ON c.id_auteur2 = au_2.id ORDER BY ref DESC LIMIT 10;
Malheureusement, le serveur de online me retourne toujours la même réponse :

Erreur dans l'execution de la requete 'SELECT c.titre, c.ref, c.detail_instru, c.prix, i.instrument, c.id_auteur1, c.id_auteur2, au_1.nom AS nom1, au_2.nom AS nom2 FROM catalogue AS c INNER JOIN Instruments AS i ON c.id_instrument = i.id LEFT JOIN Auteurs AS au_1 ON c.id_auteur1 = au_1.id LEFT JOIN Auteurs AS au_2 ON c.id_auteur2 = au_2.id ORDER BY ref DESC LIMIT 10;'. Message de MySQL : The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET SQL_MAX_JOIN_SIZE=# if the SELECT is okay

Quelqu'un à une suggestion SVP ?

Merci

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

21 avr. 2006, 10:26

Le message d'erreur te dit que ta requête (du moins les JOIN) a retourné plus de lignes que le maximum autorisé ;)

Il va donc falloir revoir ta requete ou passer aux jointure en mémoires
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer