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

PHP & Base de données Discussion :

[SQL] Optimisation d'une requête


Sujet :

PHP & Base de données

  1. #1
    Membre confirmé Avatar de Sayrus
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    899
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 899
    Points : 570
    Points
    570
    Par défaut [SQL] Optimisation d'une requête
    Hello,

    Pour un système de pagination, je calcul mes pages en fonction du nombre max de records dans la bd.

    Seulement, je me demande si il n'est pas possible de ne faire qu'une seule requête au lieu de 2?

    J'en ai une avec le LIMIT x, y

    Et l'autre identique sans le LIMIT qui me retourne le nombre max d'élément.

    N'est-il pas possible d'obtenir le nombre max avec la première requête


    Exemple de requête:

    SELECT g.id, g.parentGallery, g.image, g.thumb, gc.title, gc.description FROM com_gallery AS g INNER JOIN com_gallery_content AS gc ON g.id= gc.galleryId WHERE gc.languageId=1 AND g.type="gallery" AND g.status=1 AND ((g.access<=20 AND g.accessType=0) LIMIT 0, 2

    SELECT g.id, g.parentGallery, g.image, g.thumb, gc.title, gc.description FROM com_gallery AS g INNER JOIN com_gallery_content AS gc ON g.id= gc.galleryId WHERE gc.languageId=1 AND g.type="gallery" AND g.status=1 AND ((g.access<=20 AND g.accessType=0)

    Merci beaucoup.

  2. #2
    Rédacteur

    Homme Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 695
    Points : 1 071
    Points
    1 071
    Par défaut
    que je sache, ce n'est pas possible.
    Par contre ton code est optimisable

    1) ceci est la partie commune
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $common_sql = "FROM com_gallery AS g INNER JOIN com_gallery_content AS gc ON g.id= gc.galleryId WHERE gc.languageId=1 AND g.type='gallery' AND g.status=1 AND ((g.access<=20 AND g.accessType=0)";
    (il est préférable de mettre les quotes comme je les ai mis et non l'inverse)

    2) Calcul du total
    Au lieux de tout braser, utilise le SQL !!!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $total_sql = "SELECT COUNT(*) as nb ".$common_sql;
    tu auras directement le nombre voulu dans nb

    3) enfin la dernière, telle que tu l'as faite
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $page_sql = "SELECT g.id, g.parentGallery, g.image, g.thumb, gc.title, gc.description ".$common_sql." LIMIT 0, 2";

  3. #3
    Membre confirmé Avatar de Sayrus
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    899
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 899
    Points : 570
    Points
    570
    Par défaut
    OK merci pour cette correction

    Seulement petite question:

    Pourquoi inverser les quotes???

    Justement j'ai construit mes requêtes avec des ' ' au lieu de " " pour que PHP n'interprète pas le contenu de la requête et donc ainsi gagner du temps d'execution.

  4. #4
    Rédacteur

    Homme Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 695
    Points : 1 071
    Points
    1 071
    Par défaut
    Justement j'ai construit mes requêtes avec des ' ' au lieu de " " pour que PHP n'interprète pas le contenu de la requête et donc ainsi gagner du temps d'execution.
    Oui, mais si on fait généralement ça pour PHP/HTML, c'est pour la lisibilité, et aussi la perf.
    les attributs HTML sont logiquement entourés de ", il est donc plus simple de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    echo '<tag att="toto">titi</tag>';
    Par contre, les string dans les requètes MySQL doivent être entourés de ' , il est donc plus simple d'écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $sql = "SELECT toto FROM titi WHERE tata='tutu'";
    L'idée majeur étant finalement la lisibilé, même si les perf peuvent éventuellement compter

  5. #5
    Membre confirmé Avatar de Sayrus
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    899
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 899
    Points : 570
    Points
    570
    Par défaut
    Un grand merci pour ces précisions

  6. #6
    Membre confirmé Avatar de Sayrus
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    899
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 899
    Points : 570
    Points
    570
    Par défaut
    Les requêtes et le COUNT(*) marchent très bien excepté pour une requête un peu plus complexe où le COUNT(*) me retourne 3 au lieu de 1.

    Voici ma requête:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $query=$query_search_pages='SELECT DISTINCT p.id, pc.title, p.date';
    $common_query='FROM pages AS p INNER JOIN pages_content AS pc ON p.id=pc.pageId INNER JOIN pages_lines_content AS plc ON pc.pageId=plc.pageId WHERE (pc.title LIKE "%' . $keywords . '%" OR plc.content_left LIKE "%' . $keywords . '%" OR plc.content_center LIKE "%' . $keywords . '%" OR plc.content_right LIKE "%' . $keywords . '%") AND pc.languageId=' . (int)$_SESSION['language_id'] . ' AND plc.languageId=' . (int)$_SESSION['language_id'] . '  AND p.access <= ' . (int)$_SESSION['access'] . ' AND p.status=1 AND((Now() BETWEEN p.dateStart AND p.dateEnd) OR (p.dateStart="0000-00-00" AND p.dateEnd="0000-00-00"))' . $orderBy;
     
     $all = mysql_request('SELECT  DISTINCT COUNT(*) AS nb' . ' ' . $common_query);
    Comment ce fait-il que je n'obtienne pas le même nombre de ligne avec la première requête et celle du COUNT(*) ?

    Pourtant la requête commune est identique ? (logique)

    Un grand merci pour vos lumières...

  7. #7
    Membre averti
    Avatar de UNi[FR]
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Juin 2002
    Messages
    340
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information

    Informations forums :
    Inscription : Juin 2002
    Messages : 340
    Points : 448
    Points
    448
    Par défaut
    Citation Envoyé par wamania Voir le message
    que je sache, ce n'est pas possible.
    ...
    2) Calcul du total
    Au lieux de tout braser, utilise le SQL !!!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $total_sql = "SELECT COUNT(*) as nb ".$common_sql;
    tu auras directement le nombre voulu dans nb
    ...

    Il faut éviter les SELECT COUNT(*) et mettre à la place SELECT COUNT(id) c'est un gain en performance qui est important sur les grosse BDD

  8. #8
    Rédacteur

    Homme Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 695
    Points : 1 071
    Points
    1 071
    Par défaut
    oui c'est vrai
    enfin dans ton cas je dirais COUNT(p.id)

  9. #9
    Membre émérite Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 023
    Points : 2 273
    Points
    2 273
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Il faut éviter les SELECT COUNT(*) et mettre à la place SELECT COUNT(id) c'est un gain en performance qui est important sur les grosse BDD
    T'es sûr de ton coup il me semblait justement que le count(*) était optimisé pour ca ? (ca doit être écrit quelquepart dans la doc...).
    D'autre part tu peux utiliser SQL_CALC_FOUND_ROWS et FOUND_ROWS() si t'es en >=4.0, pour effectuer une seule requête.
    Bye

    [edit]Ah nan en fait c'est juste optimisé pour les requêtes sans where le count(*)
    [/edit]

  10. #10
    Rédacteur

    Homme Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 695
    Points : 1 071
    Points
    1 071
    Par défaut
    on en apprend tous les jours.
    Merci pour ces infos Djakisback, en effet, c'est super pratique

  11. #11
    Membre confirmé Avatar de Sayrus
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    899
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 899
    Points : 570
    Points
    570
    Par défaut
    Donc il vaut mieux utiliser un COUNT(id) et non un COUNT(*) ?

  12. #12
    Rédacteur

    Homme Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 695
    Points : 1 071
    Points
    1 071
    Par défaut
    en fait, comme l'a dit Djakisback, regarde plutôt dans la doc MySQL les fonctions :
    D'autre part tu peux utiliser SQL_CALC_FOUND_ROWS et FOUND_ROWS() si t'es en >=4.0

  13. #13
    Membre confirmé Avatar de Sayrus
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    899
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 899
    Points : 570
    Points
    570
    Par défaut
    Ok merci

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Lecture et optimisation d'une requête SQL
    Par jbrasselet dans le forum Langage SQL
    Réponses: 2
    Dernier message: 01/10/2007, 16h34
  2. [PL/SQL] Optimisation d'une requête (like?)
    Par elyo66 dans le forum SQL
    Réponses: 15
    Dernier message: 01/06/2007, 20h44
  3. Optimisation d'une requête SQL
    Par Michel601 dans le forum Oracle
    Réponses: 3
    Dernier message: 08/03/2007, 16h17
  4. Optimisation d'une requête SQL
    Par gaboo_bl dans le forum Oracle
    Réponses: 18
    Dernier message: 23/10/2006, 16h33
  5. [MySQL] Optimisation d'une requête sql
    Par fabien14 dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 18/09/2006, 12h45

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