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 :

[Mysql4] Un peu d'adie pour optimiser ma requete


Sujet :

Requêtes MySQL

  1. #1
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    1 027
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 027
    Points : 1 164
    Points
    1 164
    Par défaut [Mysql4] Un peu d'adie pour optimiser ma requete
    Salut,

    J'ai un petit souci avec une de mes requetes qui est un peu longues à s'executer.

    Bon alors vla la requete en question :

    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
    28
    29
    30
    31
    32
    33
    34
    35
     
    SELECT 	P.`idproduit`, 
    			CASE 
    				WHEN P_desc.`pourcentage` = - 1 AND P_desc.`prix_barre` = - 1
    				THEN P_desc.`prix_ht` 
    				ELSE 
    				CASE 
    					WHEN P_desc.`pourcentage` != - 1
    					THEN P_desc.`prix_ht` - ( (P_desc.`pourcentage` * P_desc.`prix_ht` ) / 100 ) 
    					ELSE P_desc.`prix_barre` 
    				END 
    			END 
    			AS `test` 
    			, P_desc.`prix_barre` 
    			, P_desc.`prix_ht` 
    	FROM 	`produit` P, `produit_famille` P_f , `produit_description` P_desc , `marque` M
    	WHERE 	P_desc.`produit_idproduit` = P.`idproduit` 
    	AND 	P_f.`idproduit` = P_desc.`produit_idproduit`
    	AND 	P_f.`idproduit` = P.`idproduit`
    	AND 	P_f.`idfamille` = '29'
    	AND		M.`idmarque` = P_desc.`idmarque`
    	AND 	P.`idproduit` 
    		= (
    			SELECT 
    				CASE 
    				WHEN SUM( S.`nbr_produit` ) >0
    				THEN S.`idproduit` 
    				END AS `idproduitstock` 
    			FROM 	`stock` S, `boutique` B
    			WHERE 	S.`idboutique` = B.`idboutique` 
    			AND 	B.`internet` = 'true'
    			AND		S.`idproduit` = P.`idproduit`
    		)
    	GROUP BY  P_desc.`couleur` , P.`idgroupe`
    ORDER BY P_desc.`titre` ASC

    Après quelques essais ect j'en ai déduit que ma requete ralentissez à cause de cette contrainte :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    	AND 	P.`idproduit` 
    		= (
    			SELECT 
    				CASE 
    				WHEN SUM( S.`nbr_produit` ) >0
    				THEN S.`idproduit` 
    				END AS `idproduitstock` 
    			FROM 	`stock` S, `boutique` B
    			WHERE 	S.`idboutique` = B.`idboutique` 
    			AND 	B.`internet` = 'true'
    			AND		S.`idproduit` = P.`idproduit`
    		)
    Donc en faites j'aimerais le remplacer par quelque chose de plus performatn... Mais je ne sais pas quoi..


    Merci par avance

  2. #2
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    1 027
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 027
    Points : 1 164
    Points
    1 164
    Par défaut
    Bon bah j'ai trouvé

    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
    28
    29
    30
    31
    32
    33
    34
    35
     
    SELECT 	P.`idproduit`, 
    			CASE 
    				WHEN P_desc.`pourcentage` = - 1 AND P_desc.`prix_barre` = - 1
    				THEN P_desc.`prix_ht` 
    				ELSE 
    				CASE 
    					WHEN P_desc.`pourcentage` != - 1
    					THEN P_desc.`prix_ht` - ( (P_desc.`pourcentage` * P_desc.`prix_ht` ) / 100 ) 
    					ELSE P_desc.`prix_barre` 
    				END 
    			END 
    			AS `test` 
    			, P_desc.`prix_barre` 
    			, P_desc.`prix_ht` ,
    			(
    			SELECT 
    				CASE 
    				WHEN SUM( S.`nbr_produit` ) >0
    				THEN S.`idproduit` 
    				END AS `idproduitstock` 
    			FROM 	`stock` S, `boutique` B
    			WHERE 	S.`idboutique` = B.`idboutique` 
    			AND 	B.`internet` = 'true'
    			AND		S.`idproduit` = P.`idproduit`
    			) As `stock`
    	FROM 	`produit` P, `produit_famille` P_f , `produit_description` P_desc , `marque` M
    	WHERE 	P_desc.`produit_idproduit` = P.`idproduit` 
    	AND 	P_f.`idproduit` = P_desc.`produit_idproduit`
    	AND 	P_f.`idproduit` = P.`idproduit`
    	AND 	P_f.`idfamille` = '29'
    	AND		M.`idmarque` = P_desc.`idmarque`
    	GROUP BY  P_desc.`couleur` , P.`idgroupe`
    	HAVING `stock` >0
    ORDER BY P_desc.`titre` ASC
    ainsi je suis passé de 1.5 sec d'execution a 0.09.... no comment !

    Bye

  3. #3
    Rédacteur
    Avatar de pcaboche
    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    2 785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Singapour

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 785
    Points : 9 716
    Points
    9 716
    Par défaut Re: [Mysql4] Un peu d'adie pour optimiser ma requete
    Au niveau de la jointure:

    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
    SELECT ...
     
    FROM produit P
     
    INNER JOIN produit_famille P_f
    ON (P_f.idproduit = P.idproduit)
     
    INNER JOIN produit_description P_desc
    ON (P_f.idproduit = P_desc.produit_idproduit)
     
    INNER JOIN marque M
    ON (M.idmarque = P_desc.idmarque)
     
    INNER JOIN stock S
    ON (S.idproduit = P.idproduit)
     
    INNER JOIN boutique B
    ON (S.idboutique = B.idboutique)
     
    WHERE P_f.idfamille = 29
    AND B.internet = 'true'
     
    GROUP BY  P_desc.couleur, P.idgroupe
     
    HAVING SUM(S.nbr_produit) >0
    Au niveau du select, il y a peut-être plus simple. On va y réfléchir...
    "On en a vu poser les armes avant de se tirer une balle dans le pied..."
    -- pydévelop

    Derniers articles:

    (SQL Server) Introduction à la gestion des droits
    (UML) Souplesse et modularité grâce aux Design Patterns
    (UML) Le Pattern Etat
    Autres articles...

  4. #4
    Rédacteur
    Avatar de pcaboche
    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    2 785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Singapour

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 785
    Points : 9 716
    Points
    9 716
    Par défaut
    Le temps de comprendre le problème de trouver une solution et de tout réécrire, il a bien fallu 10 minutes...
    "On en a vu poser les armes avant de se tirer une balle dans le pied..."
    -- pydévelop

    Derniers articles:

    (SQL Server) Introduction à la gestion des droits
    (UML) Souplesse et modularité grâce aux Design Patterns
    (UML) Le Pattern Etat
    Autres articles...

  5. #5
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    1 027
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 027
    Points : 1 164
    Points
    1 164
    Par défaut
    Salut,

    Merci pour ta réponse ! Je vais essayer et te dire ce que sa donne !

    Ceci dit peux tu m'expliquer l'interet de la clause INNER JOIN par rapport à = stp ???


    Encore merci

  6. #6
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    1 027
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 027
    Points : 1 164
    Points
    1 164
    Par défaut
    Mouarf c'est encore mieux

    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
    SELECT 	P.`idproduit`, 
    			CASE 
    				WHEN P_desc.`pourcentage` = - 1 AND P_desc.`prix_barre` = - 1
    				THEN P_desc.`prix_ht` 
    				ELSE 
    				CASE 
    					WHEN P_desc.`pourcentage` != - 1
    					THEN P_desc.`prix_ht` - ( (P_desc.`pourcentage` * P_desc.`prix_ht` ) / 100 ) 
    					ELSE P_desc.`prix_barre` 
    				END 
    			END 
    			AS `test` 
    			, P_desc.`prix_barre` 
    			, P_desc.`prix_ht`
    FROM produit P 
    INNER JOIN produit_famille P_f 
    ON (P_f.idproduit = P.idproduit) 
     
    INNER JOIN produit_description P_desc 
    ON (P_f.idproduit = P_desc.produit_idproduit) 
     
    INNER JOIN marque M 
    ON (M.idmarque = P_desc.idmarque) 
     
    INNER JOIN stock S 
    ON (S.idproduit = P.idproduit) 
     
    INNER JOIN boutique B 
    ON (S.idboutique = B.idboutique) 
     
    WHERE P_f.idfamille = 29 
    AND B.internet = 'true' 
     
    GROUP BY  P_desc.couleur, P.idgroupe 
     
    HAVING SUM(S.nbr_produit) >0
    0.04 sec de temps d'execution

    Merci

  7. #7
    Rédacteur
    Avatar de pcaboche
    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    2 785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Singapour

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 785
    Points : 9 716
    Points
    9 716
    Par défaut
    Pas de problème !

    J'avais déjà donné un début d'explications ici:
    http://www.developpez.net/forums/viewtopic.php?t=425429

    Maintenant plus en détails:

    Tout d'abord, d'un point de vue lisibilité, l'intérêt d'un INNER JOIN, c'est que l'on fait explicitement la différence entre le conditions liées à la jointure (en condition du ON), des conditions restrictives (en condition du WHERE). Sur des requêtes assez longues (comme la tienne), on sent tout de suite la différence (j'ai perdu un peu de temps à essayer de trouver les conditons restrictives).

    Ensuite, il se peut que MySQL fasse des optimisations sur les jointures (Détails dans le chapitre 13 du manuel: tout ce qui commence par "How MySQL optimizes ..."). Si tel est le cas, ces optimisations se font en se basant sur les conditions de jointure.

    Maintenant, est-ce que tu souhaites de l'aide concernant l'expression "test" présente dans le SELECT?
    "On en a vu poser les armes avant de se tirer une balle dans le pied..."
    -- pydévelop

    Derniers articles:

    (SQL Server) Introduction à la gestion des droits
    (UML) Souplesse et modularité grâce aux Design Patterns
    (UML) Le Pattern Etat
    Autres articles...

  8. #8
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    1 027
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 027
    Points : 1 164
    Points
    1 164
    Par défaut
    Si tu as une idée pour le rendre plus lisible et plus perofmant je veux bien car c'est assez nouveau pour moi les CASE, et instructions similaires, donc j'ai fait un peu comme ja'ai pu !

    Encore merci Sa fait plaisir

  9. #9
    Rédacteur
    Avatar de pcaboche
    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    2 785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Singapour

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 785
    Points : 9 716
    Points
    9 716
    Par défaut
    Tout sur les test conditionnels ici:
    http://dev.mysql.com/doc/refman/5.1/...functions.html


    Je trouve ça à peine plus lisible (avis personnel) :

    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
    IF (
      # Si reduction
      P_desc.pourcentage != - 1,
     
      (1-P_desc.pourcentage/100) * P_desc.prix_ht,
     
      IF (
        # Si prix barre
        P_desc.prix_barre != -1,
        P_desc.prix_barre,
     
        # Prix normal
        P_desc.prix_ht
      )
    ) AS test
    Et je préfère encore sans les commentaires (que j'ai ajouté parce qu'on dit souvent qu'il faut en mettre, pour la compréhension)

    Sinon, pourquoi utiliser une valeur réservée (-1) ? A la place tu pourrais utiliser la valeur NULL.
    "On en a vu poser les armes avant de se tirer une balle dans le pied..."
    -- pydévelop

    Derniers articles:

    (SQL Server) Introduction à la gestion des droits
    (UML) Souplesse et modularité grâce aux Design Patterns
    (UML) Le Pattern Etat
    Autres articles...

  10. #10
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    1 027
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 027
    Points : 1 164
    Points
    1 164
    Par défaut
    Pas de raisons particulières si ce n'est que sa parle tout seul. On à jamais vu une réduction de -1% ou un produti au pris de -1 euro.

    Pour ce qui est du IF c'est joliment vu parceque sur la page de control flow sur dev.mysql.com, je n'avais pas trouvé comment m'en servir pour mon cas.

    En tout cas encore merci c'etait très instructif tout cela

  11. #11
    Rédacteur
    Avatar de pcaboche
    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    2 785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Singapour

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 785
    Points : 9 716
    Points
    9 716
    Par défaut
    Citation Envoyé par ePoX
    Pas de raisons particulières si ce n'est que sa parle tout seul. On à jamais vu une réduction de -1% ou un produti au pris de -1 euro.
    Ca, j'avais bien compris... Mais bon, en même temps, comme on a une valeur NULL à notre disposition, autant s'en servir ! (à l'inverse, de nombreux théoriciens considèrent que le langage SQL se base trop sur la valeur NULL, mais c'est un débat dans lequel je ne souhaite pas m'engager)


    Citation Envoyé par ePoX
    En tout cas encore merci c'etait très instructif tout cela
    Pas de problème, on est là pour apprendre, échanger des points de vue et poser des questions.
    "On en a vu poser les armes avant de se tirer une balle dans le pied..."
    -- pydévelop

    Derniers articles:

    (SQL Server) Introduction à la gestion des droits
    (UML) Souplesse et modularité grâce aux Design Patterns
    (UML) Le Pattern Etat
    Autres articles...

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

Discussions similaires

  1. Aide pour Optimiser une Requete
    Par Thanwiel dans le forum Langage SQL
    Réponses: 10
    Dernier message: 06/12/2007, 10h31
  2. SOS pour optimiser ma requete sous DB2
    Par xibaarinfo dans le forum Langage SQL
    Réponses: 4
    Dernier message: 02/08/2007, 18h18
  3. Réponses: 2
    Dernier message: 17/08/2006, 11h49
  4. Aide pour optimiser une requete
    Par Akanath dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 15/09/2005, 11h05
  5. [DirectDraw] Que faire pour optimiser le rendu ???
    Par mat.M dans le forum DirectX
    Réponses: 8
    Dernier message: 12/12/2003, 18h02

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