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

SQL Oracle Discussion :

Modification / Optimisation requete


Sujet :

SQL Oracle

  1. #1
    Membre Expert
    Avatar de Emmanuel Lecoester
    Profil pro
    Inscrit en
    Février 2003
    Messages
    1 493
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Février 2003
    Messages : 1 493
    Par défaut Modification / Optimisation requete
    Bonjour messieurs dames,

    J'ai deux tables

    mvt (id_mvt, id_affaire, mt_mvt)
    reg (id_reg, id_mvt, id_affaire, mt_reg)

    Le but est de récupérer pour une affaire ses montants dans mvt mais aussi les montants dans reg sachant qu'un mouvement peut avoir 0 ou plusieurs reglements

    Première idée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    select id_affaire, sum(mt_mvt), sum(mt_reg)
    from mvt left outer reg on mvt.id_mvt = reg.id_mvt
                                   and mvt.id_affaire = reg.id_affaire
    where mvt.id_affaire = :pid
    group by id_affaire ;
    Sauf que là mes montants dans mvt sont multipliés par le nombre d'enregistrements de reg. => pas bien

    Deuxième idée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    select id_affaire, (select sum(mt_mvt) 
                            from mvt
                            where mvt.id_affaire = :pid) mt_mvt,
                           (select sum(mt_reg) 
                            from reg
                            where reg.id_affaire = :pid
                            and exists (select 1 
                                           from mvt 
                                           where mvt.id_mvt = reg.id_mvt)) mt_reg
    from dual ;
    Là çà fonctionne mais on remarque qu'on passe deux fois sur la table mvt (c'est uen table à 20 millions d'enreg et reg à 100 millions). => requete un peu lente

    Ma question : existe-t-il une méthode pour faire une sorte de "rupture" sur mvt.id_affaire du genre sum(mt_mvt distinct id_affaire)

    Merci d'avance.

  2. #2
    McM
    McM est déconnecté
    Expert confirmé

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Billets dans le blog
    4
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT id_affaire, SUM(mt_mvt), SUM(mt_reg)
    FROM (
    	SELECT id_mvt, id_affaire, mt_mvt,
    	                    (SELECT SUM(mt_reg) 
    	                     FROM REG
    	                     WHERE reg.id_affaire = mvt.id_affaire 
    			AND reg.id_mvt 	= mvt.id_mvt) mt_reg
     
    	FROM MVT
    	WHERE mvt.id_affaire = :pid
    	)
    GROUP BY id_affaire

  3. #3
    Membre Expert
    Avatar de Emmanuel Lecoester
    Profil pro
    Inscrit en
    Février 2003
    Messages
    1 493
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Février 2003
    Messages : 1 493
    Par défaut
    Merci pour ta proposition, je compare les explain et je vous tiens au courant.

  4. #4
    Membre Expert
    Avatar de Emmanuel Lecoester
    Profil pro
    Inscrit en
    Février 2003
    Messages
    1 493
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Février 2003
    Messages : 1 493
    Par défaut
    Celà fonctionne, l'explain semble correct mais le temps d'exécution est supérieur pour récupérer toutes mes affaires (11 minutes sans rendre la main) au temps de la deuxième idée (3 minutes) :s

  5. #5
    Rédacteur

    Homme Profil pro
    Développeur et DBA Oracle
    Inscrit en
    Octobre 2006
    Messages
    878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur et DBA Oracle

    Informations forums :
    Inscription : Octobre 2006
    Messages : 878
    Par défaut
    Salut,

    J'ai une petite remarque sur la solution de MCM
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    (SELECT SUM(mt_reg) 
    	                     FROM REG
    	                     WHERE reg.id_affaire = mvt.id_affaire 
    			AND reg.id_mvt 	= mvt.id_mvt) mt_reg
    A la place on met ca
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    (SELECT SUM(mt_reg) 
    	                     FROM REG
    	                     WHERE reg.id_affaire = mvt.id_affaire 
    			AND reg.id_mvt 	= mvt.id_mvt
                and mvt.id_affaire = :pid) mt_reg

  6. #6
    Membre Expert
    Avatar de Emmanuel Lecoester
    Profil pro
    Inscrit en
    Février 2003
    Messages
    1 493
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Février 2003
    Messages : 1 493
    Par défaut
    Oui salim11 mais le but est de faire cette requete pour toute les affaires donc la solution de MCM me convient en terme syntaxique

  7. #7
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    la fonction analytique SUM me parait bien utile dans ce cas

  8. #8
    Rédacteur

    Homme Profil pro
    Développeur et DBA Oracle
    Inscrit en
    Octobre 2006
    Messages
    878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur et DBA Oracle

    Informations forums :
    Inscription : Octobre 2006
    Messages : 878
    Par défaut
    Bonjour ,

    Je n'ai pas bien compris une chose, dans la requette dans la clause where
    WHERE mvt.id_affaire = :pid donc tu vas chercher les montants mt_mvt et mt_reg de l'affaire :pid, Alors la mettre dans la clause where et dans la clause de la sous-requette pour moi ca va te donner uniquement les montant d'une affaire bien preçise
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT id_affaire, SUM(mt_mvt), SUM(mt_reg)
    FROM (
    	SELECT id_mvt, id_affaire, mt_mvt,
    	                    (SELECT SUM(mt_reg) 
    	                     FROM REG
    	                     WHERE reg.id_affaire = mvt.id_affaire 
    			AND reg.id_mvt 	= mvt.id_mvt) mt_reg
    	
    	FROM MVT
    	WHERE mvt.id_affaire = :pid	)
    GROUP BY id_affaire

  9. #9
    McM
    McM est déconnecté
    Expert confirmé

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Billets dans le blog
    4
    Par défaut
    Je me souviens que j'avais fait ceci pour une question de perf :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT id_affaire, SUM(mt_mvt) / DECODE(COUNT(reg.idreg), 0,1, COUNT(reg.irreg)), 
    				SUM(mt_reg)
    FROM mvt LEFT OUTER reg ON mvt.id_mvt = reg.id_mvt
                            AND mvt.id_affaire = reg.id_affaire
    WHERE mvt.id_affaire = :pid
    GROUP BY id_affaire

  10. #10
    Rédacteur

    Homme Profil pro
    Développeur et DBA Oracle
    Inscrit en
    Octobre 2006
    Messages
    878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur et DBA Oracle

    Informations forums :
    Inscription : Octobre 2006
    Messages : 878
    Par défaut
    Salut ,

    Si on essaie ce code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT   id_affaire, SUM (mt_mvt) mt_mvt, (SELECT SUM (mt_reg)
                                                 FROM reg
                                                WHERE :pid = id_affaire) mt_reg
        FROM mvt
       WHERE mvt.id_affaire = :pid
    GROUP BY id_affaire

  11. #11
    McM
    McM est déconnecté
    Expert confirmé

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Billets dans le blog
    4
    Par défaut
    J'y avais pensé, mais si un REG correspond à une affaire sans MVT, c'est pas bon.
    C'est pour ça qu'il fait un EXISTS dans sa seconde requete.

  12. #12
    Rédacteur

    Homme Profil pro
    Développeur et DBA Oracle
    Inscrit en
    Octobre 2006
    Messages
    878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur et DBA Oracle

    Informations forums :
    Inscription : Octobre 2006
    Messages : 878
    Par défaut
    salut,

    J'ai compris, mais on peux rajouter une condition
    id_mvt is not null, comme ca on va éliminer les reglements qui n'ont pas de mouvements
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT   id_affaire, SUM (mt_mvt) mt_mvt, (SELECT SUM (mt_reg)
                                                 FROM reg
                                                WHERE :pid = id_affaire and 
                                                 id_mvt is not null ) mt_reg
        FROM mvt
       WHERE mvt.id_affaire = :pid
    GROUP BY id_affaire

  13. #13
    Membre Expert
    Avatar de Emmanuel Lecoester
    Profil pro
    Inscrit en
    Février 2003
    Messages
    1 493
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Février 2003
    Messages : 1 493
    Par défaut
    Citation Envoyé par salim11
    salut,

    J'ai compris, mais on peux rajouter une condition
    id_mvt is not null, comme ca on va éliminer les reglements qui n'ont pas de mouvements
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT   id_affaire, SUM (mt_mvt) mt_mvt, (SELECT SUM (mt_reg)
                                                 FROM reg
                                                WHERE :pid = id_affaire and 
                                                 id_mvt is not null ) mt_reg
        FROM mvt
       WHERE mvt.id_affaire = :pid
    GROUP BY id_affaire
    Dans ce cas là on prend tous les reg même des autres mouvements de l'affaire.

  14. #14
    Membre Expert
    Avatar de Emmanuel Lecoester
    Profil pro
    Inscrit en
    Février 2003
    Messages
    1 493
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Février 2003
    Messages : 1 493
    Par défaut
    Citation Envoyé par McM
    Je me souviens que j'avais fait ceci pour une question de perf :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT id_affaire, SUM(mt_mvt) / DECODE(COUNT(reg.idreg), 0,1, COUNT(reg.irreg)), 
    				SUM(mt_reg)
    FROM mvt LEFT OUTER reg ON mvt.id_mvt = reg.id_mvt
                            AND mvt.id_affaire = reg.id_affaire
    WHERE mvt.id_affaire = :pid
    GROUP BY id_affaire
    Je croyais que c'étais bon mais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SUM(mt_mvt) / DECODE(COUNT(reg.idreg), 0,1, COUNT(reg.irreg))
    Avec :
    mvt reg
    100 50
    100 50
    200 200

    donne (100+100+200) / 3 => 400/3 => 133 alors qu'il me faut 300
    Il faudrait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SUM(mt_mvt /DECODE(COUNT(reg.idreg), 0,1, COUNT(reg.irreg)))
    Sauf que là oracle n'aime pas trop

  15. #15
    Membre Expert
    Avatar de Emmanuel Lecoester
    Profil pro
    Inscrit en
    Février 2003
    Messages
    1 493
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Février 2003
    Messages : 1 493
    Par défaut
    Citation Envoyé par orafrance
    la fonction analytique SUM me parait bien utile dans ce cas
    Je suis preneur de toute piste car j'ai beau lire le cours sur les fonctions analytiques je n'y comprend toujours rien

  16. #16
    Rédacteur

    Homme Profil pro
    Développeur et DBA Oracle
    Inscrit en
    Octobre 2006
    Messages
    878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur et DBA Oracle

    Informations forums :
    Inscription : Octobre 2006
    Messages : 878
    Par défaut
    Salut,

    il va faire la somme de tous les réglements de différents mouvements (non null) pour une affaire

  17. #17
    Membre Expert
    Avatar de Emmanuel Lecoester
    Profil pro
    Inscrit en
    Février 2003
    Messages
    1 493
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Février 2003
    Messages : 1 493
    Par défaut
    OK. merci pour l'explication mais la requete ne passe pas le parseur : "not a single group function" sur la somme du reg

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT   id_affaire, SUM (mt_mvt) mt_mvt, (SELECT SUM (mt_reg)
                                                 FROM reg
                                                WHERE :pid = id_affaire AND 
                                                 id_mvt IS NOT NULL ) mt_reg
        FROM mvt
       WHERE mvt.id_affaire = :pid
    GROUP BY id_affaire

  18. #18
    Membre Expert
    Avatar de Emmanuel Lecoester
    Profil pro
    Inscrit en
    Février 2003
    Messages
    1 493
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Février 2003
    Messages : 1 493
    Par défaut
    J'ai tenté les fonctions analytiques mais sans succès

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT id_affaire, 
        SUM(mt_mvt)  OVER (PARTITION BY reg.id_affaire) mt_mvt,
        SUM(mt_reg) OVER (PARTITION BY reg.id_affaire) mt_reg
    FROM mvt LEFT OUTER reg ON mvt.id_mvt = reg.id_mvt
                            AND mvt.id_affaire = reg.id_affaire
    WHERE mvt.id_affaire = :pid
    Bien sur le montant des reglement est correct mais pas celui des mouvement car il somme toutes les lignes de id_affaire alors que je voudrait qu'il somme toutes les lignes avec le id_mvt distinct :s


    Une fois de plus je n'ai pas de bol avec cette approche

  19. #19
    Rédacteur

    Homme Profil pro
    Développeur et DBA Oracle
    Inscrit en
    Octobre 2006
    Messages
    878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur et DBA Oracle

    Informations forums :
    Inscription : Octobre 2006
    Messages : 878
    Par défaut
    Salut,

    Je pense il faut utiliser le group by rollup ou group by cube

    essaie ce code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    select mvt.id_affaire,mvt.id_mvt,reg.id_reg , sum(mt_mvt),sum(reg.mt_reg)
    from mvt LEFT OUTER join   reg ON mvt.id_mvt = reg.id_mvt
                            AND mvt.id_affaire = reg.id_affaire
    where  mvt.id_affaire = :pid
    group by rollup(mvt.id_affaire,mvt.id_mvt,reg.id_reg)
    Il me donne le résultat suivant
    la somme par id_affaire , id_affaire-id_mvt-id_reg, id_affaire-id_mvt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    ID_AFFAIRE  ID_MVT  ID_REG   SUM(MT_MVT)	SUM(REG.MT_REG)
     
    10	      1	     1	        30	               1000
    10	      1	     2	        30	               4000
    10	      1	     3	        30	               5000
    10	      1		        90	               10000
    10	      2	     4	        60	               10000
    10	      2		        60                     10000
    10			       150	               20000
    			       150                     20000

  20. #20
    Membre Expert
    Avatar de Emmanuel Lecoester
    Profil pro
    Inscrit en
    Février 2003
    Messages
    1 493
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Février 2003
    Messages : 1 493
    Par défaut
    Citation Envoyé par salim11
    Salut,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    ID_AFFAIRE  ID_MVT  ID_REG   SUM(MT_MVT)	SUM(REG.MT_REG)
     
    10	      1	     1	        30	               1000
    10	      1	     2	        30	               4000
    10	      1	     3	        30	               5000
    10	      1		        90	               10000
    10	      2	     4	        60	               10000
    10	      2		        60                     10000
    10			       150	               20000
    			       150                     20000
    Merci beaucoup pour ton investissement mais celà ne répond pas encore à mon besoin . Voilà ce que je souhaiterais en me basant sur ton cas

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    ID_AFFAIRE  ID_MVT  ID_REG   SUM(MT_MVT)	SUM(REG.MT_REG)
     
    10	      1	     1	        30	               1000
    10	      1	     2	          	               4000
    10	      1	     3	          	               5000
    10	      1		        30	               10000
    10	      2	     4	        60	               10000
    10	      2		        60                     10000
    10			       90	               20000
    			       90                     20000
    Le montant au niveau du mvt 1 doit bien être égal à 30 au final pas 30*3 (réglements).

    Sinon tu m'a appris un nouvel ordre Oracle

    Merci encore pour ton aide.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Optimisation requete
    Par mic79 dans le forum PostgreSQL
    Réponses: 6
    Dernier message: 26/04/2005, 16h35
  2. optimisation requetes (besoin de votre avis)
    Par seb92 dans le forum Requêtes
    Réponses: 2
    Dernier message: 21/12/2004, 11h27
  3. [PL/SQL] Optimisation requete SQL
    Par CDRIK dans le forum Langage SQL
    Réponses: 3
    Dernier message: 14/10/2004, 09h52
  4. [SYBASE] optimisation requete UPDATE
    Par metheorn dans le forum Sybase
    Réponses: 8
    Dernier message: 24/05/2004, 17h01
  5. Optimisation requetes SQL
    Par joel90 dans le forum Administration
    Réponses: 18
    Dernier message: 15/05/2004, 21h45

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