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 :

Optimisation de requêtes avec EXISTS


Sujet :

Requêtes MySQL

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2
    Points : 3
    Points
    3
    Par défaut Optimisation de requêtes avec EXISTS
    Bonjour à tous,

    Je suis un peu coincé avec une requète qui fonctionne, mais est horriblement lente...

    Voici le Topo, j'ai une table Order, Status et Order_Status qui fait le lien entre les deux. Le but est d'assigner un ou plusieurs status à une commande, et de pouvoir ensuite faire une recherche des commandes qui comporte ou ne comporte pas tel et tel status.


    Voici la requète:
    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
     
    SELECT `o`.* 
    FROM `Order` AS `o` 
    WHERE (
    	EXISTS (
    		SELECT Order_Id 
    		FROM Order_Status AS os2 
    			LEFT JOIN `Status` AS s2 ON os2.Status_Id = s2.Status_Id 
    			WHERE s2.Status_Const = 'STATUS1' 
    				AND o.Order_Id = os2.Order_Id
    		)
    	) AND (
     
    		EXISTS (
    			SELECT Order_Id 
    			FROM Order_Status AS os2 
    				LEFT JOIN `Status` AS s2 ON os2.Status_Id = s2.Status_Id 
    			WHERE s2.Status_Const = 'STATUS2' 
    			AND o.Order_Id = os2.Order_Id
    			)
    	) AND (
    		NOT EXISTS (
    			SELECT Order_Id 
    			FROM Order_Status AS os2 
    				LEFT JOIN `Status` AS s2 ON os2.Status_Id = s2.Status_Id 
    			WHERE s2.Status_Const = 'STATUS3' 
    			AND o.Order_Id = os2.Order_Id
    			)
    		);
    Je ne sais pas si c'est le plus adapté, mais pour l'instant c'est le seul moyen que j'ai trouvé...

    Si qqun à une idée pour optimiser ça, je suis preneur :

    Merci,

    Asfa

  2. #2
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Si je comprends le sens de la requête, vous cherchez les Order ayant le Status_Const 'STATUS1' et 'STATUS2' et pas le 'STATUT3' ?

    Dans la requête ci-dessous, il n'y a plus qu'une sous-requête NOT EXISTS. Comme on cherche des Orders qui ont un Status_Const, je pense que INNER JOIN sera meilleur que LEFT JOIN. Ça devrait réduire beaucoup le nombre de lignes à tester avec la sous-requête car les jointures seront faites probablement avant la condition NOT EXISTS.

    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
    SELECT o.*
    FROM order AS o
    INNER JOIN order_status AS os ON os.Order_Id = o.Order_Id
      INNER JOIN Status AS s ON s.Status_Id = os.Status_Id
      INNER JOIN order_status AS os2 ON os2.Order_Id = os.Order_Id
        INNER JOIN Status AS s2 ON s2.Status_Id = os2.Status_Id
    WHERE s.Status_Const = 'STATUS1'
      AND s2.Status_Const = 'STATUS2'
      AND NOT EXISTS (
        SELECT *
        FROM order_status AS os3
          INNER JOIN Status AS s3 ON s3.Status_Id = os3.Status_Id
        WHERE s3.Status_Const = 'STATUS3'
          AND os3.Order_Id = os.Order_ID
      )
    Et bien sûr, pour que la requête pédale un peu plus vite qu'un escargot, il faut que toutes les colonnes figurant dans les conditions de jointures, c'est à dire toutes les clés étrangères, soient indexées, ainsi que Status_Const pour accélérer la recherche des valeurs.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    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 !

Discussions similaires

  1. Optimiser la requête avec un plan d'exécution
    Par irnbru dans le forum Développement
    Réponses: 1
    Dernier message: 20/08/2008, 00h07
  2. optimisation de requête avec plusieurs union
    Par Smix007 dans le forum SQL
    Réponses: 11
    Dernier message: 02/04/2008, 16h59
  3. Optimisation de requête avec jointure textuelle
    Par spirou33 dans le forum Requêtes et SQL.
    Réponses: 10
    Dernier message: 26/10/2007, 09h36
  4. [CF][C#] Comment optimiser mes requêtes avec SqlCE ?
    Par david71 dans le forum Windows Mobile
    Réponses: 10
    Dernier message: 20/01/2006, 14h48
  5. Optimisation de requête avec Tkprof
    Par stingrayjo dans le forum Oracle
    Réponses: 3
    Dernier message: 04/07/2005, 09h50

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