|
Publicité ' | |||||||||||||||||||||||
|
|
#1 | ||
|
Expert Confirmé
![]() Inscription : janvier 2010 Messages : 2 706 ![]() |
Salut
Je vous fais part d'un phénomène qui me parais plutôt étrange sur une banale petite requête où le ORDER BY serait entre autre l'acteur principal. La requête à l'origine : (c'est un système de ticket interne) Code sql :
![]() Or, je sais qu'il y en a 3. -> 1 ligne ticket_id pour le user_id 100 dans la table ticket -> 3 lignes ticket_id dans la table ticket_history (3 réponses). Je supprime dans la requête le ORDER BY (ORDER BY t.date_created DESC), et hop, cette fois MySQL trouve bien les 3 lignes. Depuis quand un ORDER BY agirait sur le nombre de ligne à retourner ? Personnellement je le trouve un peu fort l'café, même ici le ORDER BY n'était pas utile. Selon vous, c'est normal ou pas ? Une explication serait le bienvenu.
__________________
Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20 Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra] |
||
|
|
00
|
|
|
#2 |
|
Membre Expert
![]() ![]() Inscription : janvier 2004 Messages : 1 238 ![]() |
Bonjour,
moi ce qui me perturbe c'est le LIMIT 1 a la fin. Si tu lui dit que tu veux un seul resultat, pourquoi il t'en retourne 2 (ou 3) ? peut etre que mysql tri la table en interne pour réaliser le group by et que ton order by "perturbe" ce tri. Essaye un order by par la meme colonne que la colonne de group by pour voir ?
__________________
PHP : Regle n°1 : mysql_query(...), mysql_connect(...) et mysq_select_db(...) doivent EN DEBUG etre suivies de or die(mysql_error()); (mais jamais en production) Regle n°2 : Mieux encore : mysql_query($requete) or die("$requete<br/>".mysql_error()); Regle n°3 : echo '<pre>';var_dump($var);echo '</pre>'; affiche le contenu et le type d'une variable. Publiez vos textes de fantasy et de science-fiction sur http://www.cercledefaeries.com/concours/ |
|
|
00
|
|
|
#3 | ||
|
Expert Confirmé
![]() Inscription : janvier 2010 Messages : 2 706 ![]() |
Citation:
D'où le COUNT(*), et d'où le LIMIT 1. Mais effectivement, j'avais déjà fait cet essai de supprimer le LIMIT 1, ça n'a rien changé au résultat du total, du COUNT(*). Citation:
![]() En faite, faut pas que ça soit la même colonne que le Group by, du moins apparemment. Si je met un tri sur la table ticket_history, ça compte bien 3 (c'est bon). Mais dès que c'est un champ de la table ticket, ça compte 2. C'est terrible ça. Alors là, c'est la 1ère fois que je remarque ça. Mais franchement, c'est normal ou pas ? Bug ou pas bug ?
__________________
Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20 Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra] |
||
|
|
00
|
|
|
#4 |
|
Membre Expert
![]() ![]() Inscription : janvier 2004 Messages : 1 238 ![]() |
ok pour le limit, en effet ^^ mais il ne sert a rien lui non plus je pense.
normal ? A priori je dirais non bug ? a priori je dirais oui Mais bon, les parseurs de SGBD sont super compliqués donc l'explication est peut etre a trouver dans le cas d'une requete super compliquée pour laquelle on a besoin de ce truc. Essaye de faire un POC (Proof Of Concept) avec des tables, des champs et des données simples et remonte le a Mysql ;o) Sinon il n'y a pas de champs NULL dans tes tables ?
__________________
PHP : Regle n°1 : mysql_query(...), mysql_connect(...) et mysq_select_db(...) doivent EN DEBUG etre suivies de or die(mysql_error()); (mais jamais en production) Regle n°2 : Mieux encore : mysql_query($requete) or die("$requete<br/>".mysql_error()); Regle n°3 : echo '<pre>';var_dump($var);echo '</pre>'; affiche le contenu et le type d'une variable. Publiez vos textes de fantasy et de science-fiction sur http://www.cercledefaeries.com/concours/ |
|
|
00
|
|
|
#5 | |
|
Expert Confirmé
![]() Inscription : janvier 2010 Messages : 2 706 ![]() |
Citation:
Mais ce qui devient de plus en plus étrange, voir même plus inquiétant, c'est que je ne parviens pas à reproduire l'erreur. Vite fait comme ça, j'ai créer une autre Bdd, tables ... et fait quelques essais des plus basiques avec les fonctions mysql_*. Et là, avec ou sans ORDER BY, ou de LIMIT, tout est cohérent. Vu que dans le projet en question j'utilise PDO, abstraction et tunti quanti ... qui commence à devenir un peu usine à gaz, peut être que ... Donc je veux bien faire un PROC (jamais fais ça d'ailleurs). Mais je me dis qu'avant d'ameuter tout l'quartier, j'aimerais bien reproduire cette erreur dans un autre contexte (en gros). Une affaire à suivre, mais il doit avoir une explication, en espérant que c'est pas l'arbre qui cache la foret.
__________________
Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20 Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra] |
|
|
|
00
|
|
|
#6 |
|
Membre Expert
![]() ![]() Inscription : janvier 2004 Messages : 1 238 ![]() |
Si tu n'arrives pas a reproduire le problème en repartant de zero, il faut faire l'inverse : partir du problème et simplifier tout au maximum petit a petit, en vérifiant a chaque suppression que le problème est toujours là.
Commence a faire une copie de ta base et de ton code pour ne pas casser tout ce que tu as fait, puis : * Fait une page avec uniquement la requete qui pose probleme * Supprime toutes les tables, champs et autres qui ne sont pas dans la requete * Supprime tout ce qui est inutile dans le code PHP en gardant la meme architecture (POO) * Supprime la couche d'abstraction PDO (c'est peut etre un bug de la couche aussi, va savoir ^^) * etc... Evidemment, ca prend du temps et ce n'est peut être pas ta priorité, mais si tu veux fouiller pour comprendre pourquoi, y a que ca a faire je crois ^^
__________________
PHP : Regle n°1 : mysql_query(...), mysql_connect(...) et mysq_select_db(...) doivent EN DEBUG etre suivies de or die(mysql_error()); (mais jamais en production) Regle n°2 : Mieux encore : mysql_query($requete) or die("$requete<br/>".mysql_error()); Regle n°3 : echo '<pre>';var_dump($var);echo '</pre>'; affiche le contenu et le type d'une variable. Publiez vos textes de fantasy et de science-fiction sur http://www.cercledefaeries.com/concours/ |
|
|
00
|
|
|
#7 |
|
Expert Confirmé
![]() Inscription : janvier 2010 Messages : 2 706 ![]() |
Effectivement, c'est tout ça qui va falloir que je fasse pour avoir un minimum d'info avant de fusiller MySQL
(je déconne). N'empêche que j'étais à des années lumières de tout ça, en postant ici j'étais quasi convaincu que c'était le SQL qui n'allait pas. En tout cas faut bien voir que c'est quasi une pure coïncidence que je tombe dessus. Normalement je ne devais pas mettre ce ORDER BY, c'est ma manie de faire du copier/coller de requêtes déjà existantes, j'ai pas du faire gaffe à l'époque. Donc quelque part c'est un mal pour un bien. Je vais quand même tenter de "jouer" des 2 cotés : D'un coté tenter de reproduire cette erreur dans un contexte le plus neutre possible. De l'autre (le site) tenter de voir quel serait le truc le plus perturbateur. Si c'est ma classe PDO ... c'est la mer** ![]() Et oui, je sens que ça va me prendre du temps cette histoire. ![]() Mais comme on dit ici : "Il faut que je trouve le boute". (-> l'erreur)
__________________
Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20 Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra] |
|
|
00
|
|
|
#8 | ||
|
Expert Confirmé
![]() Inscription : janvier 2010 Messages : 2 706 ![]() |
Bon, j'ai refais d'autres essai, et hier, le café n'était peut être pas assez fort.
J'ai recréé une Bdd, autres tables (même nom, même structure, même données), et là j'ai pu reproduire la même erreur. J'ai aussi réduit la requête au stricte minimum : Code sql :
En faisant des essais bruts de décoffrage (en local toujours) avec 4 requêtes : -> requêtes avec mysql_* sur les nouvelles tables (autre site/répertoire) -> requêtes avec mysql_* sur les tables de mon projet -> requête avec PDO sur les nouvelles tables (autre site/répertoire) -> requête avec PDO sur les tables de mon projet Les 4 donnent les même erreur si je laisse le ORDER BY Les 4 donnent les bons résultats en supprimant le ORDER BY ou en indiquant un autre champ (ticket_status_history) que la table "ticket" (où cette dernière n'est pas logique). En appliquant ces requêtes dans PhpMyAdmin, même constat. Mais aussi, j'ai créé les mêmes tables avec SQLiteManager (donc une Bdd SQLite), et là, quelque soit la requête, les résultats sont correctes, donc même avec un ORDER BY illogique. Une fois exécuté cette requête, si je clique dans "modifier" (le SQL), ça vire automatiquement le ORDER BY quelque peu foireux. Donc quelque part l'API détecte bien un problème, et même le corrige. SQLite serait il plus intelligent que MySQL ? Rien qu'avec, j'en conclus quand même que le code de mon projet ne serait pas en cause, et même la Bdd. Ouff ... J'ai tendance à dire que c'est MySQL qui déconne un peu, que cette erreur serait un peu déboussolé. Mais alors là, à quel niveau ??? Là ça me dépasse. Personnellement, j'ai pas trop envie de m'enquiquiner plus longtemps avec ça, car de toute manière ça part d'une requête qui est foireuse. Un ORDER BY s'appliquant sur une mauvaise table au minimum si on enlève le COUNT(*). Ou si on laisse le COUNT(*), le ORDER BY ne sert strictement à rien.
__________________
Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20 Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra] |
||
|
|
00
|
|
|
#9 |
|
Membre Expert
![]() ![]() Inscription : janvier 2004 Messages : 1 238 ![]() |
déjà tu as pu cerner un peu plus le problème et innocenter ton API ;o)
__________________
PHP : Regle n°1 : mysql_query(...), mysql_connect(...) et mysq_select_db(...) doivent EN DEBUG etre suivies de or die(mysql_error()); (mais jamais en production) Regle n°2 : Mieux encore : mysql_query($requete) or die("$requete<br/>".mysql_error()); Regle n°3 : echo '<pre>';var_dump($var);echo '</pre>'; affiche le contenu et le type d'une variable. Publiez vos textes de fantasy et de science-fiction sur http://www.cercledefaeries.com/concours/ |
|
|
00
|
|
|
#10 |
|
Membre régulier
![]() Nicolas Étudiant Inscription : mai 2010 Messages : 308 ![]() |
T'as des doublons dans tes réponses à sortir? Si oui, il faut utiliser DISTINCT (bon je pense que tu le savais déjà, mais juste au cas ou
|
|
|
00
|
|
|
#11 |
|
Membre Expert
![]() ![]() Inscription : janvier 2004 Messages : 1 238 ![]() |
non, c'est son count(*) qui renvoie 2 au lieu de 3 elements
mais on pourrait essayer count(distinct table.cle) ^^
__________________
PHP : Regle n°1 : mysql_query(...), mysql_connect(...) et mysq_select_db(...) doivent EN DEBUG etre suivies de or die(mysql_error()); (mais jamais en production) Regle n°2 : Mieux encore : mysql_query($requete) or die("$requete<br/>".mysql_error()); Regle n°3 : echo '<pre>';var_dump($var);echo '</pre>'; affiche le contenu et le type d'une variable. Publiez vos textes de fantasy et de science-fiction sur http://www.cercledefaeries.com/concours/ |
|
|
00
|
|
|
#12 |
|
Expert Confirmé
![]() Inscription : janvier 2010 Messages : 2 706 ![]() |
Nom mais, il n'y pas vraiment à se torturer l'esprit à vouloir trouver une solution, la question n'est pas là.
La solution est toute trouvée et ça depuis le début : Dans mon cas il n'y avais absolument pas à mettre un tri (un ORDER BY). Faire un tri sur un champ qui lui même n'est pas renvoyé, c'était absurde. De plus, c'était un champ dans la table où il y avait qu'1 seule et unique ligne, ce qui était doublement absurde. On peu dire que j'avais commis une erreur de syntaxe, ou du moins une instruction SQL illogique. En faite, le truc c'était de faire un petit retour sur un comportement de MySQL qui m'a semblé un peu troublant, voir même un peu fort (l'café). En faite, j'aurais plus vu 2 cas suivant cette requête : - Soit MySQL juge que cette erreur illogique est anodine, et donc parviendra à retourner un résultat toujours correcte, cohérent. - Soit MySQL juge que cette erreur est suffisamment grave (le résultat risque d'être incohérent), et bien dans ce cas retourne une erreur. Et bien non, c'est ni l'un ni l'autre, mais à mon sens fait pire, MySQL retourne un résultat incohérent, et ça tout en silence, sans le moindre avertissement. Donc la question : Est ce normal qu'une Base De Donnée telle que MySQL ait un comportement comme ça fasse à ce genre d'erreur ? Il y a erreur tout de même. Pour ma part, c'est pas normal, et j'aurais préféré 100 fois une belle erreur. D'ailleurs, un essai a démontré que SQLite était plus robuste, retournait le bon résultat fasse à cette même erreur. Tant qu'il s'agit d'une application sans aucun enjeu ça va. Mais imaginez un instant que l'on "brasse" de l'argent, et bien 2 n'est pas équivalent de 3, et ça peu représenter un sacré gros paquet selon la quantité "brassée" et le temps avant de trouver l'erreur. Pas cool MySQL Quoi que, ça dépend à qui profite le crime ![]() M'enfin, il n'y a pas mort d'homme non plus.
__________________
Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20 Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra] |
|
|
00
|
Copyright © 2000-2012 - www.developpez.com