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 :

Requête trop longue à simplifier ?


Sujet :

Requêtes MySQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 11
    Par défaut Requête trop longue à simplifier ?
    Bonjour à tous et à toutes,

    J'ai un énorme souci avec une de mes requêtes MySQL en php.
    Je dispose de plusieurs tables et voici ma requête principale qui met beaucoup 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
    $reqHoraire1 = mysql_query("SELECT `IdCourse`,`IdEtablissement`,`IdArret` FROM `Horaire` WHERE
    							`IdCourse` IN (SELECT `IdCourse` FROM `Course` WHERE `Sens`='".$_POST['rechSens']."')
    						AND	(`IdEtablissement` LIKE '%, ".$_POST['rechEtablissement'].",%'
    						  OR `IdEtablissement` LIKE '".$_POST['rechEtablissement'].",%'
    						  OR `IdEtablissement` LIKE '%,".$_POST['rechEtablissement'].",%'
    						  OR `IdEtablissement` LIKE '%,".$_POST['rechEtablissement']."'
    						  OR `IdEtablissement` LIKE '".$_POST['rechEtablissement']."')
    						AND `IdCourse` IN (SELECT `IdCourse` FROM `Horaire` WHERE `IdArret` IN (SELECT `IdArret` FROM `Arret` WHERE `Trigramme`='".$_POST['rechCommuneDesservie']."'))
    						");
    J'ai l'impression que les "IN" imbriqués sont trop lourds.

    Y a-t-il un moyen de simplifier cette requête ?

    Merci d'avance pour vos réponses.

  2. #2
    Membre Expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Par défaut
    Saluton,
    Citation Envoyé par Barbutan Voir le message
    J'ai l'impression que les "IN" imbriqués sont trop lourds.

    Y a-t-il un moyen de simplifier cette requête ?
    Oui, en remplaçant les IN par des jointures.
    Par ailleurs je pense que tes LIKE alternatifs pourraient avantageusement être remplacés par un ".$_POST['rechEtablissement']." INSTR(`IdEtablissement`)
    Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
    articles : Comment émuler un tableau croisé [quasi] dynamique
    et : Une énigme mathématique résolue avec MySQL
    recommande l'utilisation de PDO (PHP5 Data Objects)

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 11
    Par défaut
    Les jointures sont assez complexes pour moi.

    J'aurai mis pour remplacer le premier IN :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $reqHoraire1 = mysql_query("SELECT IdCourse,IdEtablissement,IdArret FROM Horaire,Course WHERE Course.Sens='".$_POST['rechSens']."' AND [...]
    Mais je n'est pas de résultat.

    Je continue mes recherches et mes tests.

    Merci de m'aider.

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 11
    Par défaut
    J'ai donc remplacé mais requêtes imbriquées par du stockage en tableaux php.

    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
    $req1 = mysql_query("SELECT IdArret FROM Arret WHERE Trigramme='".$_POST['rechCommuneDesservie']."'");
    		while ($row1 = mysql_fetch_row($req1)) $tab1[].=$row1[0]; 
     
    		$req2 = mysql_query("SELECT IdCourse FROM Horaire WHERE IdArret IN('".implode("','",$tab1)."')");
    		while ($row2 = mysql_fetch_row($req2)) $tab2[].=$row2[0]; 
     
    		$req3 = mysql_query("SELECT IdCourse FROM Course WHERE Sens='".$_POST['rechSens']."'");
    		while ($row3 = mysql_fetch_row($req3)) $tab3[].=$row3[0]; 
     
    		$reqHoraire1 = mysql_query("SELECT IdCourse,IdEtablissement,IdArret FROM Horaire WHERE
    							IdCourse IN('".implode("','",$tab3)."')
    						AND	(`IdEtablissement` LIKE '%, ".$_POST['rechEtablissement'].",%'
    						  OR `IdEtablissement` LIKE '".$_POST['rechEtablissement'].",%'
    						  OR `IdEtablissement` LIKE '%,".$_POST['rechEtablissement'].",%'
    						  OR `IdEtablissement` LIKE '%,".$_POST['rechEtablissement']."'
    						  OR `IdEtablissement` LIKE '".$_POST['rechEtablissement']."')
    						AND IdCourse IN('".implode("','",$tab2)."')
    						");
    Ca va rudement plus vite que les IN.

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 11
    Par défaut
    Pour remplacer les LIKE,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    IdEtablissement REGEXP '(^|([^0-9]))".$_POST['rechEtablissement']."(([^0-9])|$)'
    C'est équivalent ?

  6. #6
    Membre Expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Par défaut
    Le problème des REGEXP, outre leur syntaxe peu abordable (en tout cas pour moi), c'est leur éventuelle gourmandise en ressources.
    As-tu essayé la syntaxe avec INSTR que je t'ai proposée ?
    Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
    articles : Comment émuler un tableau croisé [quasi] dynamique
    et : Une énigme mathématique résolue avec MySQL
    recommande l'utilisation de PDO (PHP5 Data Objects)

  7. #7
    Membre chevronné
    Avatar de argoet
    Inscrit en
    Mai 2002
    Messages
    582
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 582
    Par défaut
    Au vue de votre requête et indépendamment de l'établissement

    Vous avez ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT IdCourse,IdEtablissement,IdArret 
    FROM Horaire WHERE IdCourse IN (SELECT IdCourse FROM Course WHERE Sens=:Le_Sens
    AND IdCourse IN (SELECT IdCourse FROM Horaire WHERE IdArret IN (SELECT IdArret FROM Arret WHERE Trigramme=:Le_Trigramme
    Alors peut etre , inspirez vous de cela
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Select H.IdCourse, H.IdEtablissement, H.IdArret 
    From   Arret A , Course C , Horaire H 
    Where  H.IdCourse  = C.IdCourse
    And    H.IdArret   = A.IdArret 
    And    C.Sens      = :Le_Sens
    And    A.Trigramme = :Le_Trigramme

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 11
    Par défaut
    Bonjour,

    Merci de mettre sur la voie Mister Argoet.

    J'ai donc ce code à présent :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT Horaire.IdCourse, Horaire.IdEtablissement, Horaire.IdArret
    FROM Horaire, Arret, Course
    WHERE Horaire.IdCourse = Course.IdCourse
    AND Horaire.IdArret = Arret.IdArret
    AND Course.Sens = :Le_Sens
    AND Arret.Trigramme = :Le_Trigramme
    AND Horaire.IdEtablissement REGEXP '(^|([^0-9]))XXXXX(([^0-9])|$)'
    Problème : le résultat n'est pas le même. Pourtant ce code à l'air équivalent au code d'origine.

    Quant à M'sieur Maljuna Kris, je ne vois pas comment mettre en place l'instruction INSTR.

    Le champ "IdEtablissement" comporte des identifiants séparés par des virgules avec des espaces ou non. EX : {10, 102, 33,25,47 , 478, 1247, 1475}
    Le POST recherché peut donc se trouver au début, à la fin, une virgule ou un espace avant, une virgule ou un espace après, et surtout pas de chiffrte avant ni après. D'où l'expression REGEX ci-dessus.

    As-tu une idée du code équivalent avec l'instruction INSTR ?

    Merci d'avance.

Discussions similaires

  1. Requête trop longue en VBA
    Par NicoMon dans le forum VBA Access
    Réponses: 4
    Dernier message: 07/08/2007, 11h25
  2. requéte trop longue sous ie
    Par devboy dans le forum Général Conception Web
    Réponses: 2
    Dernier message: 16/05/2007, 17h43
  3. Réponses: 4
    Dernier message: 15/05/2007, 11h10
  4. [Requête] Requête trop longue
    Par Ithilien dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 08/01/2007, 11h58
  5. [MySQL] Requête trop longue ?
    Par Thomas1434 dans le forum PHP & Base de données
    Réponses: 14
    Dernier message: 24/03/2006, 22h55

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