Ralentissement/Bug

Eléphant du PHP | 65 Messages

28 févr. 2007, 19:29

Bonjour à tous !

Voilà j'ai un soucis sur ma version n°3 de beansoldier.com

J'ai donc une page qui execute une requête qui affiche tous les boosters (ensemble de cartes) d'une langue (Français par exemple).

Cette page donne chaque booster muni d'un lien vers cette page ci :
<?php 
// on se connecte à MySQL 
$db = mysql_connect('***', '***', '***'); 

// on sélectionne la base 
mysql_select_db('***',$db); 

// on crée la requête SQL 
if(isset($_GET['Numero_Booster'])) 
{ 
// on crée la requête SQL 
$sql = 'SELECT * FROM Cartes LEFT JOIN Versions USING (Numero_Carte) LEFT JOIN Boosters USING (Numero_Booster) WHERE Boosters.Numero_Booster='.$_GET['Numero_Booster'].' ORDER BY Reference_Carte ASC'; 
}

// on envoie la requête 
$req = mysql_query($sql) or die('Erreur SQL !<br>
<font face="Book Antiqua" size="2">'.$sql.'<br>'.mysql_error()); 

// on fait une boucle qui va faire un tour pour chaque enregistrement 
while($data = mysql_fetch_assoc($req)) 
    { 

switch($data['Type_Carte_US']){ 
case "Normal Monster Card": $couleur_rangee = "#BC9456"; break;
case "Effect Monster Card": $couleur_rangee = "#AB582C"; break;
case "Flip-Effect Monster Card": $couleur_rangee = "#AB582C"; break;
case "Ritual Monster Card": $couleur_rangee = "#0D62BF"; break;
case "Effect Ritual Monster Card": $couleur_rangee = "#0D62BF"; break;
case "Fusion Monster Card": $couleur_rangee = "#8B4D9D"; break;
case "Effect Fusion Monster Card": $couleur_rangee = "#8B4D9D"; break;
case "Normal Spell Card": $couleur_rangee = "#0C8180"; break;
case "Continuous Spell Card": $couleur_rangee = "#0C8180"; break;
case "Quick-Play Spell Card": $couleur_rangee = "#0C8180"; break;
case "Ritual Spell Card": $couleur_rangee = "#0C8180"; break;
case "Field Spell Card": $couleur_rangee = "#0C8180"; break;
case "Equip Spell Card": $couleur_rangee = "#0C8180"; break;
case "Normal Trap Card": $couleur_rangee = "#A24270"; break;
case "Continuous Trap Card": $couleur_rangee = "#A24270"; break;
case "Counter Trap Card": $couleur_rangee = "#A24270"; break;
}

    // on affiche les informations de l'enregistrement en cours 
    echo '</font><div align="center">
  <center>
  <table cellpadding="0" cellspacing="0" style="border-collapse: collapse; border-left-style:dotted; border-left-width:0; border-right-style:dotted; border-right-width:0; border-top-style:dotted; border-top-width:0; border-bottom-width:0" bordercolor="#111111" width="800" id="AutoNumber1" background="http://www.beansoldier.com/Version3/Fonds/fond1.jpg">
    <tr>
      <td width="20%" align="center" bgcolor="'. $couleur_rangee .'">
      <font face="Book Antiqua" style="font-size: 11pt"><a href="http://www.beansoldier.com/Cartes/FR/DetailCarte'.$data['Type_Carte'].'FRFR.php?Numero_Carte='.$data['Numero_Carte'].'&Numero_Booster='.$data['Numero_Booster'].'&Numero_Version='.$data['Numero_Version'].'">'.$data['Reference_Carte'].'</a></font></td>
      <td width="50%" align="center" bgcolor="'. $couleur_rangee .'">
      <font face="Book Antiqua" style="font-size: 11pt"><a href="http://www.beansoldier.com/Cartes/FR/DetailCarte'.$data['Type_Carte'].'FRFR.php?Numero_Carte='.$data['Numero_Carte'].'&Numero_Booster='.$data['Numero_Booster'].'&Numero_Version='.$data['Numero_Version'].'">'.$data['Nom_FR'].'</a></font></td>
      <td width="30%" align="center" bgcolor="'. $couleur_rangee .'">
      <font face="Book Antiqua" style="font-size: 11pt">'.$data['Type_Carte_FR'].'</font></td>
    </tr>
  </table>
  </center>
</div><font face="Book Antiqua" size="2">';
    } 

// on ferme la connexion à mysql 
mysql_close(); 
?>
Or dès que je veux cliquer sur un lien pour atteindre cette page, la chargement est infini et il ne met pas d'erreur, il charge dans le vent.

Est-ce un problème au niveau de mon codage ? Mon hebergeur dis que ce ne peut etre que ca car au niveau serveur il n'y a aucun soucis...

Seul chose que j'ai remarqué, un ralentissement conséquent au moment ou j'ai inséré dans ma base une table de 18000 entrées environs.

Donc si quelu'un aurait une idée de la nature du problème je lui serai reconnaissant de m'en faire part.

Pour testé :

http://www.beansoldier.com/Cartes/FR/CartesFR.php

Si vous cliquez sur un des élément il va chargé dans le vent (il se peut que le tout premier marche, mais si vous reesayé ca ne marchera pas)

Eléphant du PHP | 65 Messages

02 mars 2007, 12:19

Aucune idée ? :(

Bon ca lag toujours sauf le premier clic mais bon j'ai beau cherché je ne trouve rien :cry:

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

02 mars 2007, 20:38

Essaie de poster le résultat d'un EXPLAIN pour voir ? (je te laisse utiliser le moteur de recherche si tu ne sais pas comment)

Eléphant du PHP | 65 Messages

02 mars 2007, 21:53

Code : Tout sélectionner

id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE boosters const PRIMARY PRIMARY 4 const 1 Using temporary; Using filesort 1 SIMPLE cartes ALL NULL NULL NULL NULL 2414 1 SIMPLE versions ALL NULL NULL NULL NULL 18055 Using where
Bon je calle pas grand chose, d'après ce que j'ai il faut faire :

1 * 2414 * 18055 = 43 584 770

Mais j'ai du mal a capté la j'ai mis 202 au pif car Numero_Booster est un INT (7) que je le cherche par rapport a un numéro déjà prédéfini donc bon je voi pas trop a quoi ca va me servir


en plus sur beansoldier.free.fr ca marchait sans prob :cry:

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

03 mars 2007, 09:56

EXPLAIN nous donne toutes sortes d'informations très intéressantes. Premièrement, comme je m'en doutais la table "boosters" apparait en premier alors que dans ta requête elle apparait en troisième position. C'est parce que MySQL a été assez intelligent pour comprendre que tu t'étais trompé de jointures et surtout d'ordre pour les tables.

Ta requête originale:

Code : Tout sélectionner

SELECT * FROM Cartes LEFT JOIN Versions USING (Numero_Carte) LEFT JOIN Boosters USING (Numero_Booster) WHERE Boosters.Numero_Booster = 202 ORDER BY Reference_Carte ASC
Je te conseille de relire le manuel au sujet des jointures LEFT JOIN. Le principe de cette jointure est de lire les enregistrements de la table de "gauche" puis d'y ajoindre les enregistrements correspondants de la table de droite à chaque fois que cela est possible. Ta requête telle qu'elle est formulée voudrait dire "lis toute la table de cartes, puis toute la table de versions, puis essaie de voir ce que tu peux faire avec les boosters". L'autre truc important avec LEFT JOIN c'est que s'il n'y a pas de correspondance possible, l'enregistrement est renvoyé avec des NULL à la place des valeurs, alors qu'une jointure [INNER] JOIN éliminerait simplement l'enregistrement. Dans cet exemple, puisque la table "boosters" apparait dans la clause WHERE, le LEFT JOIN fonctionne comme un JOIN et MySQL le remplace discrètement car les "INNER JOIN" sont généralement plus performants que les "OUTER JOIN" (LEFT JOIN / etc...)

À part ça, qu'est-ce qu'on apprend d'EXPLAIN ? On voit beaucoup de "ALL" dont le manuel dit
ALL

Une analyse complète de la table sera faîte pour chaque combinaison de lignes issue des premières tables. Ce n'est pas bon si la première table n'est pas une jointure de type const et c'est très mauvais dans les autres cas. Normalement vous pouvez éviter ces situations de ALL en ajoutant des index basée sur des parties de colonnes.
Il te faut donc ajouter des indices sur les colonnes qui servent à faire la jointure. L'embêtant c'est que d'après ta requête je ne sais même pas quelles sont ces colonnes... :? Si "Numero_Carte" sert à identifier de façon unique un enregistrement alors l'index devrait être de type "PRIMARY". Si un index PRIMARY existe déjà alors utilise "UNIQUE". Dans tous les autres cas, un INDEX simple suffira. Pour le reste il faudrait que tu postes un schéma simplifié de tes tables ou que tu expliques comment les enregistrements sont joints entre eux. Comment joins-tu les boosters aux cartes? les cartes aux versions?

PS: à quelle table appartient Reference_Carte au fait ?

Eléphant du PHP | 65 Messages

03 mars 2007, 10:38

Et bien, je vais devoir te dire un GRAND merci !

Ca fonctionne nickel, c'est vrai que ton raisonnement est logique, même tellement !

En tout cas j'ai compris le principe désormais !

:wink: