IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Requêtes MySQL Discussion :

optimiser une reqête qui mets beaucoup de temps


Sujet :

Requêtes MySQL

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 16
    Points : 9
    Points
    9
    Par défaut optimiser une reqête qui mets beaucoup de temps
    Bonjour,

    je viens de faire une requête qui prends sur mon site environ 15 secondes avant que le résultat ne s'affiche (il y a beaucoup d'enregistrements dans les deux tables.

    1ère table: themedumois
    champs: id, titre, poeme, auteur, datedupoeme, theme, miseenpage, liencomment, valid
    2ème tables: commentaires2
    id, idpoeme, auteurpoeme, etc....

    J'effectue la requete suivante afin d'obtenir les poèmes souhaités (ici 30 au hasard) et le nombre de commentaires correspondant à chaque poème
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT themedumois.id, themedumois.titre, themedumois.poeme, themedumois.auteur, themedumois.datedupoeme, themedumois.theme, themedumois.miseenpage, themedumois.liencomment, themedumois.valid, count(commentaires2.id) as nbr
    FROM themedumois 
    LEFT JOIN commentaires2
    ON commentaires2.idpoeme = themedumois.id AND tablepoeme="themedumois"
    GROUP BY themedumois.id
    ORDER BY rand() LIMIT 0,30

    Comment faire pour alléger la requête ?

  2. #2
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 : 16 799
    Points : 34 046
    Points
    34 046
    Billets dans le blog
    14
    Par défaut
    Est-ce que les tables sont correctement indexées ?

    Normalement, un COUNT(*) devrait suffire. On ne sait jamais, ça peut peut-être accélérer un chouia la requête.

    Vous pouvez aussi essayer de déplacer la restriction sur le nom de la table dans une clause WHERE plutôt que dans la condition de jointure.

    Je vous encourage aussi à utiliser les alias partout, ça rend la lecture de la requête plus facile, peut éviter des ambigüités et évite au SGBD de chercher à quelle table appartient la colonne (ici dans la seconde partie de la condition de jointure). C'est toujours ça de gagné.

    Enfin, les valeurs textuelles se mettent normalement entre apostrophes et non pas entre guillemets.

    Ce qui donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT t.id, t.titre, t.poeme, t.auteur, t.datedupoeme, t.theme, t.miseenpage,
       t.liencomment, t.valid, count(*) AS nbr
    FROM themedumois AS t
    LEFT JOIN commentaires2 AS c
      ON c .idpoeme = t .id 
    WHERE c.tablepoeme = 'themedumois'
    GROUP BY t.id
    ORDER BY rand() LIMIT 0,30
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « 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 la suite Linux Mageïa !

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 16
    Points : 9
    Points
    9
    Par défaut
    Je vais essayer de continuer le sujet dans l'ordre, tout d'abord merci pour vos conseils.

    Pour ce qui est de l'indexage des tables, j'y ai réfléchi, mais n'est pas tout compris.
    Seuls les id auto-incrémenté servent d'index
    Quels valeurs devrais-je choisir comme index pour themedumois ?

    Ensuite:
    - Le count(*) fonctionne
    - En mettant la condition dans le where, je n'obtiens que les poèmes ayant reçu des commentaires, mais les autres n'apparaissent plus
    - L'utilisation d'alias, bonne idée, j'avais oublié que cela se faisait (on va gagné en lisibilité effectivement)
    - Pour l'histoire des apostrophes au lieu des guillemets, je ne peux pas le faire car ma requête est se trouve entre apostrophe (faudrait t'il que je fasse l'inverse?)

    Merci encore pour votre soutien

    ERIC

  4. #4
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 : 16 799
    Points : 34 046
    Points
    34 046
    Billets dans le blog
    14
    Par défaut
    Citation Envoyé par rickways Voir le message
    Pour ce qui est de l'indexage des tables, j'y ai réfléchi, mais n'est pas tout compris.
    Pour plus d'info et des exemples frappants sur les index, voir le blog de SQLPro.

    Seuls les id auto-incrémenté servent d'index
    Quels valeurs devrais-je choisir comme index pour themedumois ?
    Puisqu'il y a une condition sur commentaire2.tablepoeme, il faudrait que cette colonne soit indexée.

    - En mettant la condition dans le where, je n'obtiens que les poèmes ayant reçu des commentaires, mais les autres n'apparaissent plus
    Effectivement, au temps pour moi !

    - Pour l'histoire des apostrophes au lieu des guillemets, je ne peux pas le faire car ma requête est se trouve entre apostrophe (faudrait t'il que je fasse l'inverse?)
    Je suppose qu'il s'agit d'une requête élaborée en PHP ?
    Ce n'est pas fondamental cette histoire de guillemets mais c'est plus normatif de mettre les valeurs textuelles entre apostrophes.
    Et en PHP, ce qui se trouve à l'intérieur de guillemets peut être interprété mais pas ce qui se trouve entre apostrophes.
    Personnellement, je trouve plus facile de faire ceci :
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $requete = "SELECT lesColonnes
    FROM laTable
    WHERE uneColonne = '$variable'
    ORDER BY colonneOrdre";
    Plutôt que ceci :
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $requete = 'SELECT lesColonnes
    FROM laTable
    WHERE uneColonne = "' .$variable. '"
    ORDER BY colonneOrdre';
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « 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 la suite Linux Mageïa !

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 16
    Points : 9
    Points
    9
    Par défaut
    Je tiens à m'excuser, car je n'avais pas mis la condition qui pose problème.

    En effet c'est lorsque je mets WHERE valid=1 (qui correspond aux poèmes validés, sinon c'est 0) et bien c'est là que ça met 20 secondes, sans cette condition c'est super rapide.

    Il faudrait donc que je mette en index le champs valid ????

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 16
    Points : 9
    Points
    9
    Par défaut
    Pour ce qui est de la normalité (écriture de ma requete en php) effectivement c'est plus pratique !

    Bon pour revenir au problème principal:

    la requete qui rame est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $req = '
    SELECT t.id, t.titre, t.poeme, t.auteur, t.datedupoeme, t.theme, t.miseenpage,
       t.liencomment, t.valid, count(*) AS nbr
    FROM themedumois AS t
    LEFT JOIN commentaires2 AS c
      ON c .idpoeme = t .id AND c.tablepoeme = "themedumois" 
    WHERE t.valid=1
    GROUP BY t.id
    ORDER BY nbr ASC LIMIT 0,30
     
    ';
    C'est le where t.valid=1 ou valid=1, ça donne la même chose, tout rame, dès que je l'enlève alors ça va mieux

    Mais lorsque la case valid est à 1, cela veut dire que j'ai validé le poème, si il est à 0 ça veut dire que je ne l'ai pas validé!

    Pourquoi est-ce qu'une colonne aussi simple fait tout ramer ? et surtout comment faire ?

  7. #7
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 : 16 799
    Points : 34 046
    Points
    34 046
    Billets dans le blog
    14
    Par défaut
    Si je comprends bien, la colonne valid est booléenne ?
    Inutile alors de l'indexer, le SGBD ignorera sûrement l'index car il y a trop peu de valeurs distinctes. Ceci dit, tu peux quand même essayer avec et sans index pour voir ce que ça donne.
    Tu peux aussi faire un EXPLAIN de ta requête pour voir comment MySQL la traîte.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « 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 la suite Linux Mageïa !

Discussions similaires

  1. Réponses: 6
    Dernier message: 05/03/2013, 18h33
  2. Réponses: 4
    Dernier message: 14/11/2011, 21h04
  3. Réponses: 7
    Dernier message: 10/03/2009, 19h02
  4. Réponses: 16
    Dernier message: 19/02/2008, 14h10
  5. [langage] Creer une fonction qui met en majuscule ?
    Par Cyber@l dans le forum Langage
    Réponses: 6
    Dernier message: 04/12/2003, 18h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo