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 :

Requête trop lente


Sujet :

PHP & Base de données

  1. #1
    Membre averti
    Inscrit en
    Juillet 2008
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 51
    Par défaut Requête trop lente
    Bonsoir à tous,
    Cette requête met trop de temps à s'exécuter.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    function recherche_cessation ($connexion)
    {
     
    $matricule = $_POST['matricule'];
     
    $cessations = $connexion->prepare("SELECT *  
    FROM absences A
    JOIN employes E, type_conge T 
    WHERE E.num_matricule = A.matri_employe
    AND A.id_type = T.id_type_conge
    AND A.motif ='Congés'  AND A.matri_employe = :matricule
     ");
     
    $cessations->bindParam(':matricule', $matricule, PDO::PARAM_STR); 
    $cessations->execute();
     
    return $cessations->fetch(PDO::FETCH_OBJ);
    }
     
    $lesCessation=recherche_cessation ($connexion);
     
    while( $lesCessations ) // on récupère les produits
    {
    	//j'affiche les enregistrements
     
    }$cessations->closeCursor();
    Pourrais-je avoir de l'aide pour résoudre le problème?
    Merci

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    1- bonne utilisation de JOIN
    2- SELECT * : as-tu besoin de tous les champs ? Sinon, il faut nommer ceux utiles

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $cessations = $connexion->prepare("SELECT A.champ1, A.champ2, E.champ3, T.champ4, ......
    FROM absences A
    JOIN employes E 
      ON E.num_matricule = A.matri_employe
    JOIN type_conge T 
      ON A.id_type = T.id_type_conge
    WHERE A.motif ='Congés'  
    AND A.matri_employe = :matricule
     ");

  3. #3
    Membre averti
    Inscrit en
    Juillet 2008
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 51
    Par défaut
    Bonjour jreaux62,
    J'essaie et je te reviens. Merci

  4. #4
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    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 818
    Billets dans le blog
    14
    Par défaut
    3) Les colonnes sur lesquelles portent les conditions de jointure sont-elles indexées ?
    4) Les colonnes sur lesquelles porte la restriction (clause WHERE) sont-elles indexées ?
    5) Combien y de t-il de lignes dans les tables ?
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    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
    Membre averti
    Inscrit en
    Juillet 2008
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 51
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    3) Les colonnes sur lesquelles portent les conditions de jointure sont-elles indexées ?
    4) Les colonnes sur lesquelles porte la restriction (clause WHERE) sont-elles indexées ?
    5) Combien y de t-il de lignes dans les tables ?
    Non aucune des colonnes n'est indexée.
    Il y a 13 lignes maximum dans chacune des tables.

    1- bonne utilisation de JOIN
    2- SELECT * : as-tu besoin de tous les champs ? Sinon, il faut nommer ceux utiles
    J'ai repris la requête comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    $cessations = $connexion->prepare("SELECT 
    A.matri_employe AS matricule,
    E.nom AS nom,
    E.prenom AS prenom,
    A.numerodecision AS numerodecision,
    A.date_decision AS date_decision,
    A.tranche AS tranche,
    A.date_debut AS date_debut,
    A.date_fin AS date_fin,
    T.designation_conge AS designation_conge,
    T.nbre_jour AS nbre_jour
    FROM absences A
    JOIN employes E 
      ON E.num_matricule = A.matri_employe
    JOIN type_conge T 
      ON A.id_type = T.id_type_conge
    WHERE A.motif ='Congés'  
    AND A.matri_employe = :matricule
     "
    Mais j'ai l'impression que mon while boucle à l'infini. En effet, quand je vérifie dans la table absences, seulement six ligne répondent à la requête mais la requête m'affiche plus d'une dizaine de ligne à l'écran et le navigateur plante

  6. #6
    Modératrice
    Avatar de Celira
    Femme Profil pro
    Développeuse PHP/Java
    Inscrit en
    Avril 2007
    Messages
    8 633
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeuse PHP/Java
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2007
    Messages : 8 633
    Par défaut
    Ta requête a l'air correcte (en tous cas, beaucoup plus que la 1ere version ) Tu as exécuté la requête directement sur la base ? (via PhpMyAdmin ou équivalent) Tu obtiens le bon résultat ?

    13 lignes dans chacune des 3 tables, si tu te loupes sur les jointures dans la requête et que ça remonte le produit cartésien de la totalité des lignes, tu peux potentiellement récupérer 2000 et quelques résultats

    On peut voir le code qui fait l'affichage ?
    Modératrice PHP
    Aucun navigateur ne propose d'extension boule-de-cristal : postez votre code et vos messages d'erreurs. (Rappel : "ça ne marche pas" n'est pas un message d'erreur)
    Cherchez un peu avant poser votre question : Cours et Tutoriels PHP - FAQ PHP - PDO une soupe et au lit !.

    Affichez votre code en couleurs : [CODE=php][/CODE] (bouton # de l'éditeur) et [C=php][/C]

  7. #7
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    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 818
    Billets dans le blog
    14
    Par défaut
    Non aucune des colonnes n'est indexée.
    Arf ! Chose à corriger !
    Toutes les clés étrangères doivent être indexées.
    Les colonnes sur lesquelles portent les recherches les plus probables doivent l'être aussi, sauf si elle ne sont pas discriminantes (exemple : on n'indexe pas une colonne booléenne parce qu'il n'y aura au plus que deux valeurs, même avec des millions de lignes. L'index est inutile et ne sera probablement jamais utilisé par le SGBD).

    Il y a 13 lignes maximum dans chacune des tables.
    Avec une aussi faible volumétrie, la requête devrait s'exécuter en une fraction de seconde, même sans index !

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    ON E.num_matricule = A.matri_employe
    De quel types sont les colonnes présentes dans cette jointure ?
    D'une manière générale, on ne fait les jointures que sur des identifiants de type entier parce que c'est beaucoup plus rapide que sur des colonnes de type alphanumérique.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    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 !

  8. #8
    Membre averti
    Inscrit en
    Juillet 2008
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 51
    Par défaut
    Tu as exécuté la requête directement sur la base ? (via PhpMyAdmin ou équivalent) Tu obtiens le bon résultat ?
    Oui exécuté directement sur la base ça marche bien.

    On peut voir le code qui fait l'affichage ?
    Voici le code complet :
    la fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    function recherche_cessation ($connexion,$matricule)
    {
    $cessations = $connexion->prepare("SELECT 
    A.matri_employe AS matricule,
    E.nom AS nom,
    E.prenom AS prenom,
    A.numerodecision AS numerodecision,
    A.date_decision AS date_decision,
    A.tranche AS tranche,
    A.date_debut AS date_debut,
    A.date_fin AS date_fin,
    T.designation_conge AS designation_conge,
    T.nbre_jour AS nbre_jour
    FROM absences A
    JOIN employes E 
      ON E.num_matricule = A.matri_employe
    JOIN type_conge T 
      ON A.id_type = T.id_type_conge
    WHERE A.motif ='Congés'  
    AND A.matri_employe = :matricule
     ");
     
    $cessations->bindParam(':matricule', $matricule, PDO::PARAM_STR); 
    $cessations->execute();
     
    return $cessations->fetch(PDO::FETCH_OBJ);
    }
    l'affichage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    $matricule = $_POST['matricule'];
     
    $lesCessations=recherche_cessation ($connexion,$matricule);
     
    while( $lesCessations ) // on récupère les produits
    {
    		echo "<tr> ";
     
            echo '<td align="center">'.$lesCessations->matricule.'</td>';
    		echo '<td align="center">'.$lesCessations->nom .' '.$lesCessations->prenom.'</td>';
    		echo '<td align="left" style ="padding-left:10px">'.$lesCessations->numerodecision.' du '.date("d/m/Y",strtotime($lesCessations->date_decision)).'</td>';
    		echo '<td align="center">'; if($lesCessations->tranche=="1") echo 'Première'; else echo "Deuxième"; echo'</td>';
    		echo "<td align=\"center\"> du ".date("d/m/Y",strtotime($lesCessations->date_debut))." au ".date("d/m/Y",strtotime($lesCessations->date_fin))."</td>";
    		echo '<td align="center"><a href="imp_cessation.php?tranche='.$lesCessations->tranche.'&matricule='.$matricule.'&date_decision='.date("d/m/Y",strtotime($lesCessations->date_decision)).'&numerodecision='.$lesCessations->numerodecision.'&type='.$lesCessations->designation_conge.'&nbrejr='.$lesCessations->nbre_jour.'">Imprimer</a></td>';
     
     
    }$cessations->closeCursor();
    De quel types sont les colonnes présentes dans cette jointure ?
    Les champ sont en VARCHAR

  9. #9
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    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 818
    Billets dans le blog
    14
    Par défaut
    1)
    Cette requête met trop de temps à s'exécuter
    C'est combien, "trop de temps" ?

    2)
    Les champ sont en VARCHAR
    Les champs sont à la campagne ou dans les formulaires, pas dans les tables SQL qui ne sont composées que de colonnes et de lignes.

    Comme dit dans mon précédent message, des jointures avec des colonnes en VARCHAR, c'est pas top !
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    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 !

  10. #10
    Membre averti
    Inscrit en
    Juillet 2008
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 51
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    1)
    C'est combien, "trop de temps" ?

    2)
    Les champs sont à la campagne ou dans les formulaires, pas dans les tables SQL qui ne sont composées que de colonnes et de lignes.

    Comme dit dans mon précédent message, des jointures avec des colonnes en VARCHAR, c'est pas top !
    1) Ça met plus de trois minutes pour afficher les lignes alors que directement sur la base c'est en quelques fractions de secondes.
    Par ailleurs, comme je l'ai dit plus haut, ma boucle While semble bouclé à l'infini et fait planter le navigateur (et la machine avec).

    2) Compris pour les colonnes en VARCHAR

  11. #11
    Modératrice
    Avatar de Celira
    Femme Profil pro
    Développeuse PHP/Java
    Inscrit en
    Avril 2007
    Messages
    8 633
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeuse PHP/Java
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2007
    Messages : 8 633
    Par défaut
    Ya un truc bizarre dans ton histoire : la fonction qui exécute la requête fait un seul appel à fetch, donc ne récupère que la 1ere ligne de résultat. Donc tu ne peux pas avoir plus d'une seule ligne affichée
    Modératrice PHP
    Aucun navigateur ne propose d'extension boule-de-cristal : postez votre code et vos messages d'erreurs. (Rappel : "ça ne marche pas" n'est pas un message d'erreur)
    Cherchez un peu avant poser votre question : Cours et Tutoriels PHP - FAQ PHP - PDO une soupe et au lit !.

    Affichez votre code en couleurs : [CODE=php][/CODE] (bouton # de l'éditeur) et [C=php][/C]

  12. #12
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    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 818
    Billets dans le blog
    14
    Par défaut
    Le problème est donc dans le PHP.

    Pourquoi faire une boucle while alors que vous n'avez ramené qu'une ligne avec return $cessations->fetch(PDO::FETCH_OBJ); ?
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    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 !

  13. #13
    Modératrice
    Avatar de Celira
    Femme Profil pro
    Développeuse PHP/Java
    Inscrit en
    Avril 2007
    Messages
    8 633
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeuse PHP/Java
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2007
    Messages : 8 633
    Par défaut
    Ah j'ai trouvé !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while( $lesCessations ) // on récupère les produits
    Ya pas de modification de la condition ! Donc en fait, tu affiches la même ligne en boucle infinie !

    Il faut que tu remplaces le fetch par un fetchAll et le while par un foreach.
    Modératrice PHP
    Aucun navigateur ne propose d'extension boule-de-cristal : postez votre code et vos messages d'erreurs. (Rappel : "ça ne marche pas" n'est pas un message d'erreur)
    Cherchez un peu avant poser votre question : Cours et Tutoriels PHP - FAQ PHP - PDO une soupe et au lit !.

    Affichez votre code en couleurs : [CODE=php][/CODE] (bouton # de l'éditeur) et [C=php][/C]

  14. #14
    Membre averti
    Inscrit en
    Juillet 2008
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 51
    Par défaut
    Coool! Ca marche très bien. Merci bien. Bénédictions!

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

Discussions similaires

  1. Optimisation de requêtes trop lentes..
    Par Nevrosl dans le forum Requêtes
    Réponses: 5
    Dernier message: 11/03/2010, 13h38
  2. requête trop lente
    Par smaildba dans le forum SQL
    Réponses: 9
    Dernier message: 20/04/2009, 12h20
  3. Requête trop lente
    Par shadeoner dans le forum SQL
    Réponses: 11
    Dernier message: 23/05/2008, 10h24
  4. Requête trop lente, comment l'optimiser?
    Par getz85 dans le forum Langage SQL
    Réponses: 19
    Dernier message: 29/01/2008, 13h40
  5. auto-killer une requête trop lente
    Par Nico57 dans le forum Oracle
    Réponses: 5
    Dernier message: 05/12/2006, 18h04

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