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 PostgreSQL Discussion :

Optimisation requête


Sujet :

Requêtes PostgreSQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé

    Homme Profil pro
    Consultant informatique
    Inscrit en
    Septembre 2011
    Messages
    371
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2011
    Messages : 371
    Par défaut Optimisation requête
    Bonjour,

    J'ai écri une requette qui est je pense un peu lourde. Je voudrais l'optimiser pour:
    • une meilleur lecture
    • avoir un traitement plus rapide. actuellement, la requette prend 27 secondes. je voudrais que ça soit plus rapide.


    Comme je ne sais pas ce dont vous avez besoin, je vous mets le code:
    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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    -- BalanceCPT => genere un tableau qui sont la balance comptable de mes regs. ces données sont mises à jour quotidiennement.
    With BalanceCPT AS
    (
    SELECT	rcptdet.idg_reg
    	,rcptdet.numcpt
    	,rcptdet.totdebex + rcptdet.totdebper											AS ReportDebitCPT
    	,rcptdet.totcredex + rcptdet.totcredper 										AS ReportCreditCPT
    	,rcptdet.totdebj													AS CumulDebitJourCPT
    	,rcptdet.totcredj													AS CumulCreditJourCPT
    	,rcptdet.totdebex + rcptdet.totdebper + rcptdet.totdebj									AS CumulDebitCPT
    	,rcptdet.totcredex + rcptdet.totcredper + rcptdet.totcredj								AS CumulCreditCPT
    	,CASE	WHEN 	(rcptdet.totdebex + rcptdet.totdebper + rcptdet.totdebj)-(rcptdet.totcredex + rcptdet.totcredper + rcptdet.totcredj) > 0 THEN
    			(rcptdet.totdebex + rcptdet.totdebper + rcptdet.totdebj)-(rcptdet.totcredex + rcptdet.totcredper + rcptdet.totcredj)
    		ELSE 0.00
    		END 														AS SoldeDebitCPT
    	,CASE	WHEN 	(rcptdet.totcredex + rcptdet.totcredper + rcptdet.totcredj)-(rcptdet.totdebex + rcptdet.totdebper + rcptdet.totdebj) > 0 THEN
    			(rcptdet.totcredex + rcptdet.totcredper + rcptdet.totcredj)-(rcptdet.totdebex + rcptdet.totdebper + rcptdet.totdebj)
    		ELSE 0.00
    		END														AS SoldeCreditCPT
    FROM base.rcptdet
    ORDER BY idg_reg, numcpt
    ),
    -- avec ces données, je calcule la sommes pour chaque reg => Balance.
    Balance AS
    (
    SELECT	BalanceCPT.idg_reg		AS Numreg
    	,SUM(ReportDebitCPT) 		AS ReportDebit
    	,SUM(ReportCreditCPT) 		AS ReportCredit
    	,SUM(CumulDebitJourCPT)		AS CumulDebitJour
    	,SUM(CumulCreditJourCPT)	AS CumulCreditJour
    	,SUM(CumulDebitCPT)		AS CumulDebit
    	,SUM(CumulCreditCPT)		AS CumulCredit
    	,SUM(SoldeDebitCPT)		AS SoldeDebit
    	,SUM(SoldeCreditCPT)		AS SoldeCredit
    FROM BalanceCPT
    GROUP BY BalanceCPT.idg_reg
    )
    -- la, j'affiche les regs qui sont vides ou qui n'ont jamais dépensé ou encaisser de recette.
    Select	--RR.idreg
    	PCT.intitule		AS NomPlanComtable
    	,CATR.libelle		AS Categorie
    	,RPM.typereg		AS Typereg
    	,RR.intitule		AS Nomreg
    	,RR.num_reg		AS ID_reg_chor
    	,RPM.dteuser		AS Datereg
    	,COUNT(CASE WHEN RH.numbenef > 0 THEN 1 ELSE NULL END)	AS Nb_de_tiers
    	,RU.nom			AS Nom
    	,RU.prenom		AS Prenom
    	,RU.nomuser		AS identifiant
    	,RG.nomgroupe		AS GroupeUtilisateur
    	,Balance.SoldeDebit	AS SoldeDebit
    --	,Balance.SoldeCredit	AS SoldeCredit
    FROM base.rreg AS RR
    	LEFT JOIN base.asso_cat_reg AS ACATR  -- catégorie
    		ON RR.idreg = ACATR.idreg
    		LEFT JOIN base.cat_reg AS CATR
    			ON ACATR.id_cat_reg = CATR.id
    	LEFT JOIN base.rpasse AS RPASS  -- utilisateur et groupe
    		ON RR.idreg = RPASS.idg_reg
    		LEFT JOIN base.rutils AS RU
    			ON RPASS.numuser = RU.numuser
    		LEFT JOIN base.rgroupes AS RG
    			ON RPASS.numgroupe = RG.numgroupe
    	LEFT JOIN base.plancpt_reg AS PCPTR --nom plan comptable
    		ON RR.idreg = PCPTR.id_reg
    		LEFT JOIN base.plancpt_lib AS PCT
    			ON PCPTR.id_plancpt = PCT.id
    	LEFT JOIN Balance --balance
    		ON RR.idreg = Balance.Numreg
    	LEFT JOIN base.rparam AS RPM --date reg
    		ON RR.idreg = RPM.idg_reg
    	LEFT JOIN base.rhabitue AS RH --nombre de reg
    		ON RR.idreg = RH.idg_reg
    WHERE (RG.parent = 1 OR RG.parent = 2 OR RG.parent = 3271)
    -- condition permettant d'avoir que les regs vide = 0€ et les regs avec de l'avance 50 000€.
    AND (
    (Balance.ReportDebit = 0 AND Balance.ReportCredit = 0 AND Balance.CumulDebitJour = 0 AND Balance.CumulCreditJour = 0 AND Balance.CumulDebit = 0 AND Balance.CumulCredit = 0 AND Balance.SoldeDebit = 0 AND Balance.SoldeCredit = 0)
    OR  (Balance.ReportDebit = 0 AND Balance.ReportCredit = 0 AND Balance.CumulDebitJour = 50000 AND Balance.CumulCreditJour = 50000 AND Balance.CumulDebit = 50000 AND Balance.CumulCredit = 50000 AND Balance.SoldeDebit = 50000 AND Balance.SoldeCredit = 50000)
    OR  (Balance.ReportDebit = 50000 AND Balance.ReportCredit = 50000 AND Balance.CumulDebitJour = 0 AND Balance.CumulCreditJour = 0 AND Balance.CumulDebit = 50000 AND Balance.CumulCredit = 50000 AND Balance.SoldeDebit = 50000 AND Balance.SoldeCredit = 50000)
    )
    --AND RR.type_reg = 'RR'
    GROUP BY PCT.intitule, CATR.libelle, RPM.typereg, RR.intitule, RR.num_reg, RPM.dteuser, RU.nom, RU.prenom, RU.nomuser, RG.nomgroupe, SoldeDebit--, SoldeCredit
    ORDER BY NomPlanComtable, Categorie, Nomreg asc
    Cordialement,
    vandman

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    22 010
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 22 010
    Billets dans le blog
    6
    Par défaut
    Dans votre première CTE vous avez un ORDER BY. Ceci est syntaxiquement illégal et je m'étonne que PostGreSQL l'accepte !
    Supprimez le, il ne sert a rien.

    De plus fournissez nous la description de vos tables avec ses index. Sans cela pas de conseil possible.

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  3. #3
    Membre éclairé

    Homme Profil pro
    Consultant informatique
    Inscrit en
    Septembre 2011
    Messages
    371
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2011
    Messages : 371
    Par défaut
    Bonjour,
    Sous-quel format vous les voulez?

    Cordialement,
    Vandman

  4. #4
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 654
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 654
    Billets dans le blog
    10
    Par défaut
    Bonjour,

    Pour la description des tables et index, le plus simple est de communiquer le DDL

    Quelle est la volumétrie de chacune des tables, vu le nombre de jointures outer, la volumétrie collectée peut être très importante

    De plus, je vois que vous avez des conditions de filtrage (where) sur des montants et utilisant des conditions "OR" , ce sont donc à double titre des critères non sargables !

  5. #5
    Membre éclairé

    Homme Profil pro
    Consultant informatique
    Inscrit en
    Septembre 2011
    Messages
    371
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2011
    Messages : 371
    Par défaut
    Bonjour,

    J’espère que ça fait l'affaire.

    J'ai mis la volumétrie actuelle en commentaire et au début de chaque création de table.

    Cordialement,
    vandman
    Fichiers attachés Fichiers attachés

  6. #6
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 654
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 654
    Billets dans le blog
    10
    Par défaut
    Citation Envoyé par vandman Voir le message
    Bonjour,

    J’espère que ça fait l'affaire.

    J'ai mis la volumétrie actuelle en commentaire et au début de chaque création de table.

    Cordialement,
    vandman
    Le format fourni n'est pas très pratique à lire une mise en colonne aurait facilité la lecture
    il faut vérifier que les jointures portent sur des colonnes de même format, je l'ai controlé pour les 1eres jointures, mais pas pour toute la requete vu le nombre de tables mises en œuvre.

    A priori c'est probablement le where/or sur les montants qui est le plus couteux
    Vous pourriez essayer de pré-filtrer dès création des CTE en ajoutant une clause HAVING sur chacun des montants, puisque vous ne conservez finalement que les valeurs 0 et 50000, ce qui limiterait la casse dans le where de filtrage de la requete principale

Discussions similaires

  1. optimisation requête-regroupement info
    Par mariobedard dans le forum Langage SQL
    Réponses: 2
    Dernier message: 29/09/2005, 15h10
  2. Besoin d'aide pour optimiser requête SQL
    Par Keuf95 dans le forum Langage SQL
    Réponses: 10
    Dernier message: 06/09/2005, 16h02
  3. Optimiser requête utilisant NOT IN
    Par Neilos dans le forum Langage SQL
    Réponses: 5
    Dernier message: 11/08/2005, 14h24
  4. optimisation requête
    Par alex2205 dans le forum Décisions SGBD
    Réponses: 5
    Dernier message: 09/02/2005, 14h15
  5. optimisation requête SQL!!! help!!
    Par anathem62 dans le forum Requêtes
    Réponses: 2
    Dernier message: 24/05/2004, 16h26

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