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 et SQL. Discussion :

Performance et création d'un état (ou d'une table) à partir d'une requête UNION


Sujet :

Requêtes et SQL.

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 29
    Points : 14
    Points
    14
    Par défaut Performance et création d'un état (ou d'une table) à partir d'une requête UNION
    Bonjour à tous,

    dans un 1er temps, j'aimerais savoir s'il est possible d'améliorer le temps de calcul de mes requêtes UNION, pour la 1ère dont voici le code :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT ENCOURS2.CodeCLE, ENCOURS2.Exercice,ENCOURS2.CodeBP, ENCOURS2.Produit, ENCOURS2.PMdébut,ENCOURS2.PMfin,ENCOURS2.PMmoyenne,ENCOURS2.FGSE,Nz(CAbrut,0) AS [CA brut],Nz(CAnet,0) AS [CA net],Nz(fraisgestion,0) AS [Frais],Nz(commission,0) AS [Commission BP],Nz([Total des frais],0) AS TotalFrais
    from ENCOURS2 LEFT JOIN ACQUISITION2 ON ((ENCOURS2.CodeCLE=ACQUISITION2.CodeCLE) AND (ENCOURS2.Exercice=ACQUISITION2.Exercice) AND  (ENCOURS2.CodeBP=ACQUISITION2.CodeBP) AND (ENCOURS2.Société=ACQUISITION2.Société) AND (ENCOURS2.Produit=ACQUISITION2.Produit))
    UNION SELECT CodeCLE,Exercice,CodeBP,Produit,0,0,0,0, CAbrut, CAnet, fraisgestion,commission, [Total des frais]
    from ACQUISITION2
    WHERE CodeCLE NOT IN (SELECT CodeCLE from ENCOURS2);

    le résultat s'affiche instantanément,

    par contre la 2ème qui s'effectue à partir de la requête précédente + 1 autre table, et dont voici le code :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT R_Encours_CA.CodeCLE, R_Encours_CA.Exercice,R_Encours_CA.CodeBP, R_Encours_CA.Produit, R_Encours_CA.PMdébut,R_Encours_CA.PMfin,R_Encours_CA.PMmoyenne,R_Encours_CA.FGSE,R_Encours_CA.[CA brut],R_Encours_CA.[CA net],R_Encours_CA.Frais,R_Encours_CA.[Commission BP],R_Encours_CA.TotalFrais,Nz(Comsurencours,0)
    from R_Encours_CA LEFT JOIN CSE2 ON ((R_Encours_CA.CodeCLE=CSE2.CodeCLE) AND (R_Encours_CA.Exercice=CSE2.Exercice) AND  (R_Encours_CA.CodeBP=CSE2.CodeBP) AND (R_Encours_CA.Produit=CSE2.Produit))
    UNION SELECT CodeCLE,Exercice,CodeBP,Produit,0,0,0,0,Comsurencours,0,0,0,0,0
    from CSE2
    WHERE CodeCLE NOT IN (SELECT CodeCLE from R_Encours_CA);
    celle-ci prends plus d'une heure !

    Ensuite, j'aimerais créer un état à partir de cette requête, mais access m'explique qu' "une requête action ne peut être utilisée comme source" !

    Avez vous une solution à me proposer ?

    Merci d'avance.

  2. #2
    Modérateur

    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    15 355
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2005
    Messages : 15 355
    Points : 23 824
    Points
    23 824
    Par défaut
    Plus des pistes que des solutions :

    Pour le temps de calcul il est recommandé de ne pas utiliser IN() ou NOT IN()qui ne sont pas optimisables. Même chose pour les fonctions VBA écrites par l'utilisateur.

    Tu peux passer par une table intermédiaire où tu stockes le resultat de ta 1ère requête. Évidement il faut bien faire attention de vider cette table avant ou après usage.

    Enfin je sais qu'il est possible d'imprimer le plan d'exécution d'une requête de Access mais je ne l'ai jamais fait et je ne me souviens plus comment on fait.

  3. #3
    Membre émérite

    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 751
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 751
    Points : 2 368
    Points
    2 368
    Par défaut
    Bonjour clonezoë et marot_r !

    Pour éviter l'emploi du NOT IN, il est parfois possible de le remplacer par une jointure externe.

    Par exemple, si on se rapporte à la 1ère requête SQL donnée par clonezoë, on peut modifier le deuxième SELECT de l'UNION.

    ● 1ère requête SQL avec NOT IN:
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    UNION 
    SELECT CodeCLE,Exercice,CodeBP,Produit,0,0,0,0,CAbrut,CAnet,fraisgestion,commission,[Total des frais]
    FROM ACQUISITION2
    WHERE CodeCLE NOT IN (SELECT CodeCLE FROM ENCOURS2);
    ● 1ère requête SQL modifiée avec jointure externe à gauche:
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    UNION 
    SELECT CodeCLE,Exercice,CodeBP,Produit,0,0,0,0,CAbrut,CAnet,fraisgestion,commission,[Total des frais]
    FROM ACQUISITION2 LEFT JOIN ENCOURS2 
    ON ACQUISITION2.CodeCLE=ENCOURS2.CodeCLE 
    WHERE ENCOURS2.CodeCLE IS NULL;
    On peut appliquer la même modification sur la deuxième requête SQL, mais ça ne sera toujours pas optimal car Access exécutera deux fois la requête R_Encours_CA.
    Cependant, on devrait quand même constater une certaine amélioration...

    ● 2ème requête SQL modifiée avec jointure externe à gauche:
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    UNION 
    SELECT CodeCLE,Exercice,CodeBP,Produit,0,0,0,0,Comsurencours,0,0,0,0,0 
    FROM CSE2 LEFT JOIN R_Encours_CA 
    ON CSE2.CodeCLE=R_Encours_CA.CodeCLE 
    WHERE R_Encours_CA.CodeCLE IS NULL;

    Enfin, comme le champ CodeCLE participe à toutes les jointures, il faut absolument qu'il soit indexé dans toutes les tables où il figure.


    L'utilisation d'une table intermédiaire, comme suggéré par marot_r, permettrait sans aucun doute de faire s'effondrer le temps d'exécution de la 2ème requête.
    C'est une voie à explorer si l'utilisation de jointure externe ne suffit pas à te satisfaire.

    Bon courage !
    _

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 29
    Points : 14
    Points
    14
    Par défaut
    Bonjour et merci pour vos réponses,

    je vais m'empresser de tester tout cela et reviens vers vous pour vous dire si çà marche...ou pas...

    A +

Discussions similaires

  1. Création d'une table à partir d'une requête
    Par mbokmahop dans le forum Requêtes et SQL.
    Réponses: 9
    Dernier message: 17/11/2017, 15h53
  2. [ASE]SOS Création d'une table à partir d'une requête
    Par bilelle dans le forum Adaptive Server Enterprise
    Réponses: 1
    Dernier message: 26/09/2007, 11h39
  3. Création d'une table à partir d'une autre table en VB6
    Par mqsi dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 20/07/2007, 14h22
  4. creer un état à partir d'une seul colonne d'une table
    Par HARBAOUI dans le forum Langage SQL
    Réponses: 1
    Dernier message: 19/02/2007, 14h14
  5. Création d'une table à partir d'une requête
    Par pedroleouf dans le forum Administration
    Réponses: 16
    Dernier message: 25/10/2006, 18h18

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