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 :

Mysql : requete complexe ou multitude de requete ?


Sujet :

Requêtes MySQL

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Mysql : requete complexe ou multitude de requete ?
    Bonjour,
    je viens de passer la journée à traiter une requête complexe (outer join) pour tenter de résoudre un pb de délai de génération d'une page...
    résultat : AU SECOURS C'EST PIRE !!!

    Voici ma problématique
    j'ai 2 tables (importantes env 4000 à 5000 enregistrements) :

    une table producteur avec des producteur lié à un utilisateur (id=$IdUser) et d'autres communs (id=99999999) :
    dans mon ancien script :
    SELECT
    p1.Idproducteur, p1.Nom, p1.Ville, p1.IdUser
    FROM table1
    WHERE (p1.IdUser=$IdUser OR p1.IdUser=999999999)

    jusque là pas de pb,
    puis pour chaque p1.Idproducteur je vérifie s'il l'utilisateur a des produits...
    deuxieme sql : SELECT COUNT(*) FROM table2 WHERE Idproducteur=$Idproducteur AND IdUser=$IdUser

    moralité : + de 250 accès SQL... génération de page en 2.5 secondes, un monde

    je me dis donc qu'un seul sql rapatriant la liste
    p1.Idproducteur, p1.Nom, p1.Ville, p1.IdUser
    avec le nombre de produits de l'utilisateur à coté (1 ou 0 important car je dois aussi extraire les producteurs sans produit), et c'est gagné :

    Voilà le résulat :
    SELECT DISTINCT p1.Idproducteur, p1.Nom, p1.Ville, p1.IdUser, case when p2.Nombre>0 then 0 else 1 end as nombreprod
    FROM table1 AS p1 LEFT OUTER JOIN table AS p2 ON (p1.IdProducteur=p2.IdProducteur and p2.IdUser=$IdUser)
    WHERE (p1.IdUser=$IdUser OR p1.IdUser=999999999)

    nombreprod = 0 si il a des produits, 1 s'il en a pas

    ET CA MARCHE TRES BIEN !!!

    et là je rigole : durée du script : 14 secondes (contre 2.5 avant !)

    A moi !

  2. #2
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 284
    Points : 11 741
    Points
    11 741
    Par défaut
    quels sont tes index ?
    Antoun
    Expert Tableau, Essbase, BO, SQL

    La bible d'Essbase, 2ème édition

  3. #3
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    mes index :
    sur ma table producteur : idproducteur
    sur ma table produit : idprod, non utilisé dans cette requête

    quelle est l'influence de l'index ?

  4. #4
    Membre éprouvé Avatar de fenkys
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    376
    Détails du profil
    Informations personnelles :
    Âge : 57
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 376
    Points : 1 054
    Points
    1 054
    Par défaut
    Il y a un problème dans ta requête, la clause ON est destinée a indiquer les conditions de jointures, pas à filtrer les résultat (fonction dévolue à la clause WHERE). Mettre un filtre dans la clause ON ne peut que ralentiri le traitement par MySQL car il va travailler sur plus de résultats que nécessaire.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT DISTINCT p1.Idproducteur, p1.Nom, p1.Ville, p1.IdUser, case when p2.Nombre>0 then 0 else 1 end as nombreprod
    FROM table1 AS p1 LEFT OUTER JOIN table AS p2 ON (p1.IdProducteur=p2.IdProducteur and p1.IdUser=p2.idUser)
    WHERE p1.IdUser=$IdUser
    Ma requête ne reproduit pas vraiment ton code, mais tu peux t'en inspirer pour créer une requête correcte qui sépare bien conditions de jointures et filtrage des résultats. La solution serait en fait de ne pas mettre une valeur réelle dans ta colonne p1.IdUser mais de mettre une valeur null pour le cas général (dans ce cas, ma requête est utilisable telle quelle).

  5. #5
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 284
    Points : 11 741
    Points
    11 741
    Par défaut
    Citation Envoyé par serge1973 Voir le message
    mes index :
    sur ma table producteur : idproducteur
    sur ma table produit : idprod, non utilisé dans cette requête

    quelle est l'influence de l'index ?
    accélérer les recherches. Tu devrais indexer l'ensemble des colonnes utilisées dans les jointures et autres filtres.
    Antoun
    Expert Tableau, Essbase, BO, SQL

    La bible d'Essbase, 2ème édition

  6. #6
    Membre éprouvé
    Avatar de Sivrît
    Profil pro
    Inscrit en
    Février 2006
    Messages
    953
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2006
    Messages : 953
    Points : 1 249
    Points
    1 249
    Par défaut
    Citation Envoyé par Antoun Voir le message
    accélérer les recherches. Tu devrais indexer l'ensemble des colonnes utilisées dans les jointures et autres filtres.
    Je crois qu'ici on a très très besoin de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    CREATE INDEX IPRODUIT_PRODUCTEUR_USER ON produit(IdProducteur, IdUser);
    CREATE INDEX IPRODUCTEUR_USER ON producteur(IdUser);
    Par contre il y a un détail que je ne comprend pas : La deuxième requête d'origine utilisait un COUNT qui a laissé place à une colonne Nombre.
    Pour coller au COUNT il faudrait un GROUP BY. C'est un peu ce que fait le DISTINCT mais ça ne colle pas tout à fait.

Discussions similaires

  1. [MySQL] PHP MySql - Requete complexe
    Par tideqc dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 25/10/2012, 01h53
  2. requete complexe, jonture ou sous requete ?
    Par junglist.kirss dans le forum Requêtes
    Réponses: 6
    Dernier message: 03/12/2009, 15h19
  3. performance MySql avec des requetes complexes
    Par khadir dans le forum Requêtes
    Réponses: 3
    Dernier message: 04/12/2007, 16h40
  4. [PHP/MySql] requete complexe
    Par jfrag dans le forum Requêtes
    Réponses: 5
    Dernier message: 26/09/2006, 10h16
  5. requete complexe
    Par Thunder_nico dans le forum Langage SQL
    Réponses: 8
    Dernier message: 07/10/2004, 11h36

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