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

Langage SQL Discussion :

Etude de performance entre 2 requêtes


Sujet :

Langage SQL

  1. #1
    Membre actif
    Inscrit en
    Août 2006
    Messages
    381
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 381
    Points : 252
    Points
    252
    Par défaut Etude de performance entre 2 requêtes
    Bonjour,

    Je dois rechercher les commandes non réceptionnées et les détails de commande associées.
    Quel est parmi les deux solutions suivantes, celle qui vous semble la plus performante:

    Solution 1:
    J'utilise une vue donnant les commandes dont tous les produits n'ont pas été réceptionné et ensuite dans chacune des requête je filtre selon le client.
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    CREATE VIEW V_CDE_NONRECEPTION
    AS
    SELECT	CDE_ID, CDE_REF, STE_ID, CDE_CLI_REF, CDE_DATE, CDE_RETOUR_PREVUE
    FROM    T_COMMANDE_CDE CDE
    	INNER JOIN V_CDE_DTL DTL
    		ON CDE.CDE_ID = DTL.CDE_ID
    WHERE  DTL.LIG_CDE_QUTE_RCP < DTL.LIG_CDE_QUTE

    Requête pour la sélection des commandes:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT CDE_ID, CDE_REF, STE_ID, CDE_CLI_REF, CDE_DATE, CDE_RETOUR_PREVUE
    FROM V_CDE_NONRECEP
    WHERE STE_ID = @STE_ID

    Requête pour la sélection des détails de commandes:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT	LIG_CDE_ID, LIG_CDE_QUTE, DTL.CDE_ID, PDT_ID, PDT_REF, LIG_CDE_QUTE_RCP
    FROM	V_CDE_DTL DTL
    	INNER JOIN V_CDE_NONRECEP CDE
    		ON CDE.CDE_ID = DTL.CDE_ID
    WHERE     CDE.STE_ID = @STE_ID


    Solution 2:
    Idem que précédemment mais je n'utilise pas la vue de sélection des commande non réceptionnées.
    Requête pour la sélection des commandes:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT	CDE_ID, CDE_REF, STE_ID, CDE_CLI_REF, CDE_DATE, CDE_RETOUR_PREVUE
    FROM    T_COMMANDE_CDE CDE
    	INNER JOIN V_CDE_DTL DTL
    		ON CDE.CDE_ID = DTL.CDE_ID
    WHERE  DTL.LIG_CDE_QUTE_RCP < DTL.LIG_CDE_QUTE
    AND STE_ID = @STE_ID

    Requête pour la sélection des détails de commandes:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    SELECT	LIG_CDE_ID, LIG_CDE_QUTE, DTL.CDE_ID, PDT_ID, PDT_REF, LIG_CDE_QUTE_RCP
    FROM	V_CDE_DTL DTL
    WHERE CDE_ID IN (
    SELECT	CDE_ID
    FROM    T_COMMANDE_CDE CDE
    	INNER JOIN V_CDE_DTL DTL
    		ON CDE.CDE_ID = DTL.CDE_ID
    WHERE  DTL.LIG_CDE_QUTE_RCP < DTL.LIG_CDE_QUTE
    AND STE_ID = @STE_ID)

    Merci pour vos réponses.
    Bye

  2. #2
    Membre régulier
    Homme Profil pro
    Inscrit en
    Février 2005
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Février 2005
    Messages : 100
    Points : 113
    Points
    113
    Par défaut
    A mon avis la solution avec la vue est la meilleur car tu vas déjà restreindre le nombre de résultats retournés pour STE_ID.

    En effet dans ta solution 2, tu vas parcourir deux fois plus l'ensemble T_COMMANDE_CDE CDE INNER JOIN V_CDE_DTL DTL alors qu'une sélection sur la vue ne le fait qu'une fois. Cela suppose bien évidemment que tu n'exécute la vue qu'une fois et que tu traites ensuite avec les résultats retournés. De plus la vue est conseillé en terme de sécurité quant à l'accès au données.

  3. #3
    Membre actif
    Inscrit en
    Août 2006
    Messages
    381
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 381
    Points : 252
    Points
    252
    Par défaut
    Bonjour et merci pour la réponse,

    Citation Envoyé par sillycoder
    Cela suppose bien évidemment que tu n'exécute la vue qu'une fois
    qu'entends-tu par là ?
    Tu veux dire dans une même requête ?

    Merci d'avance.
    Bye

  4. #4
    Membre régulier
    Homme Profil pro
    Inscrit en
    Février 2005
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Février 2005
    Messages : 100
    Points : 113
    Points
    113
    Par défaut
    Oui dans ton code tu exécutes la vue et tu récupères les résultats selon la méthode proposée par ton langage de programmation et tu utilises ensuite ses résultats retournés par la vue pour lancer les deux autres requêtes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT CDE_ID, CDE_REF, STE_ID, CDE_CLI_REF, CDE_DATE, CDE_RETOUR_PREVUE
    FROM V_CDE_N ONRECEP
    WHERE STE_ID in (listing des valeurs retournées par la vue);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT	LIG_CDE_ID, LIG_CDE_QUTE, DTL.CDE_ID, PDT_ID, PDT_REF, LIG_CDE_QUTE_RCP
    FROM	V_CDE_DTL DTL
    	INNER JOIN V_CDE_NONRECEP CDE
    		ON CDE.CDE_ID = DTL.CDE_ID
    WHERE     CDE.STE_ID in (listing des valeurs retournées par la vue);
    Imaginons que la vue retourne : 42 56 et 89

    tu auras alors
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT CDE_ID, CDE_REF, STE_ID, CDE_CLI_REF, CDE_DATE, CDE_RETOUR_PREVUE
    FROM V_CDE_N ONRECEP
    WHERE STE_ID in (42, 56, 89);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT	LIG_CDE_ID, LIG_CDE_QUTE, DTL.CDE_ID, PDT_ID, PDT_REF, LIG_CDE_QUTE_RCP
    FROM	V_CDE_DTL DTL
    	INNER JOIN V_CDE_NONRECEP CDE
    		ON CDE.CDE_ID = DTL.CDE_ID
    WHERE     CDE.STE_ID in (42, 56, 89);

  5. #5
    Membre actif
    Inscrit en
    Août 2006
    Messages
    381
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 381
    Points : 252
    Points
    252
    Par défaut
    Bonjour,

    et merci pour ces explications.
    La requête pour la sélection des commandes est dans une procédure stockée.
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    CREATE PROCEDURE ReadCommandeNonRecep
    (
      @STE_ID INT
    )
    AS
    SELECT CDE_ID, CDE_REF, STE_ID, CDE_CLI_REF, CDE_DATE, CDE_RETOUR_PREVUE
    FROM V_CDE_NONRECEP
    WHERE STE_ID = @STE_ID

    L'autre requête, celle pour la sélection des détails des commandes est dans une autre procédure stockée:

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    CREATE PROCEDURE ReadDetailsCommandeNonRecep
    (
       @STE_ID INT
    )
    AS
    SELECT	LIG_CDE_ID, LIG_CDE_QUTE, DTL.CDE_ID, PDT_ID, PDT_REF, LIG_CDE_QUTE_RCP
    FROM	V_CDE_DTL DTL
    	INNER JOIN V_CDE_NONRECEP CDE
    		ON CDE.CDE_ID = DTL.CDE_ID
    WHERE     CDE.STE_ID = @STE_ID

    Côté langage de programmation, j'exécute la première procédure stockée et je récupère les résultats.
    Ensuite j'exécute la deuxième procédure stockée et je récupère les résultats.

    Est-ce ainsi que je devrais procéder ?
    Et selon toi, je devrais exécuter d'abord la vue depuis mon langage de programmation ? J'ai dû mal comprendre, c'est géré en interne par le SGBD c'est ça ?

    Merci d'avance.
    Bye

  6. #6
    Membre régulier
    Homme Profil pro
    Inscrit en
    Février 2005
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Février 2005
    Messages : 100
    Points : 113
    Points
    113
    Par défaut
    Non c'est très bien dans les procédures stockées. C'est même mieux que dans un langage car cela t'évite d'encombrer inutilement les communications avec la bases.
    Il faut exécuter ta vue dans la procédure stockée et pour chaque occurrence de la vue, il faut lancer lancer les requêtes correspondantes.

  7. #7
    Membre actif
    Inscrit en
    Août 2006
    Messages
    381
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 381
    Points : 252
    Points
    252
    Par défaut
    Bonjour,

    et merci pour la réponse.
    Ca donnerait quoi globalement ?

    Merci d'avance.
    Bye

  8. #8
    Membre régulier
    Homme Profil pro
    Inscrit en
    Février 2005
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Février 2005
    Messages : 100
    Points : 113
    Points
    113
    Par défaut
    Apparemment d'après la syntaxe, tu as l'air utiliser SQL Serveur or je ne connais qu'Oracle, Firebird et MySQL.

    Néanmoins, je vais te donner un exemple avec la syntaxe de firebird que tu pourras adapter. (les variables) est la liste de tes variables que tu souhaites afficher

    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
    38
    39
    40
    41
     
    /* déclaration de la variable (pour chaque occurrence) */
    DECLARE VARIABLE VAR_STE_ID INTEGER;
    DECLARE VARIABLE VAR_STE_IDRES VARCHAR(200);
     
    BEGIN
      VAR_STE_IDRES = '';
     
      FOR SELECT STE_ID FROM V_CDE_NONRECEPTION INTO :VAR_STE_ID DO
      BEGIN
     
       if (:VAR_STE_IDRES = '') then
       begin
         VAR_STE_IDRES = :VAR_STE_ID
       end
       else
       begin
         VAR_STE_IDRES = :VAR_STE_IDRES ||','|| :VAR_STE_ID ;
       end   
     
      END
     
      /* pour les commandes */
      FOR SELECT CDE_ID, CDE_REF, STE_ID, CDE_CLI_REF, CDE_DATE,      CDE_RETOUR_PREVUE
      FROM V_CDE_N ONRECEP
      WHERE STE_ID in (:VAR_STE_IDRES) INTO :(Tes variables pour commande) DO
      BEGIN
         supend;
      END
     
      /* pour le détail des commandes */
      SELECT	LIG_CDE_ID, LIG_CDE_QUTE, DTL.CDE_ID, PDT_ID, PDT_REF,    LIG_CDE_QUTE_RCP
      FROM	V_CDE_DTL DTL
    	INNER JOIN V_CDE_NONRECEP CDE
    		ON CDE.CDE_ID = DTL.CDE_ID
      WHERE     CDE.STE_ID in (:VAR_STE_IDRES) INTO :(Tes variables pour détail commande) DO
      BEGIN
         supend;
      END
     
    END

    ou même

    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
    38
    39
    40
    41
    /* déclaration de la variable (pour chaque occurrence) */
    DECLARE VARIABLE VAR_STE_ID INTEGER;
    DECLARE VARIABLE VAR_STE_IDRES VARCHAR(200);
    
    BEGIN
      VAR_STE_IDRES = '';
    
      FOR SELECT STE_ID FROM V_CDE_NONRECEPTION INTO :VAR_STE_ID DO
      BEGIN
    
       if (:VAR_STE_IDRES = '') then
       begin
         VAR_STE_IDRES = :VAR_STE_ID
       end
       else
       begin
         VAR_STE_IDRES = :VAR_STE_IDRES ||','|| :VAR_STE_ID ;
       end   
    
      END
    
      /* pour les commandes */
      FOR SELECT CDE_ID, CDE_REF, STE_ID, CDE_CLI_REF, CDE_DATE,      CDE_RETOUR_PREVUE
      FROM V_CDE_N ONRECEP
      WHERE STE_ID in (:VAR_STE_IDRES) INTO :(Tes variables pour commande) DO
      BEGIN
        
        /* détail de la commande*/
        SELECT	LIG_CDE_ID, LIG_CDE_QUTE, DTL.CDE_ID, PDT_ID, PDT_REF,        LIG_CDE_QUTE_RCP
        FROM	V_CDE_DTL DTL
    	INNER JOIN V_CDE_NONRECEP CDE
    		ON CDE.CDE_ID = DTL.CDE_ID
        WHERE     CDE.STE_ID = (variable de CDE_ID courant) INTO :(Tes variables pour détail commande) DO
        BEGIN
           supend;
        END
    
      END
    
    END

Discussions similaires

  1. Réponses: 15
    Dernier message: 28/06/2012, 14h19
  2. Problème de Performances entre bases avec une même requête
    Par olivier_44 dans le forum Administration
    Réponses: 4
    Dernier message: 18/04/2011, 10h22
  3. Choix entre 2 requêtes : performance ?
    Par kimaidou dans le forum Requêtes
    Réponses: 6
    Dernier message: 03/02/2011, 16h44
  4. Réponses: 4
    Dernier message: 07/01/2010, 12h27
  5. [AC-2003] Performances entre requêtes écrites dans le code ou à partir de l'interface
    Par lio33 dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 05/10/2009, 16h24

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