Précédent   Forum des professionnels en informatique > Bases de données > Langage SQL
Langage SQL Forum d'entraide sur le langage SQL et sur les questions liées à la conception de schéma (DDL). Cours SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 25/02/2011, 11h52   #1
Invité de passage
 
Inscription : mai 2008
Messages : 14
Détails du profil
Informations forums :
Inscription : mai 2008
Messages : 14
Points : 2
Points : 2
Par défaut Requête assez lente, besoin d'optimisation

Bonjour,

J'ai un souci sur une requête qui s'avère assez longue au niveau de l'éxecution.

Je vous présente la requête :
Code :
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
SELECT r.CodeEntite, r.LibelleSociete, RIGHT(r.CodeAffaire,5), r.LibelleAffaire, r.GN, p.LibellePolice, c.CodeFouE, r.SommeReglementsFISDeduites  AS SommeReglementsFisDeduites,
CASE
        WHEN r.CodePolice = '2' OR r.CodePolice = '4' THEN
                MAX(tc.ValeurF)
        ELSE
                NULL
END AS TxDec,
CASE
        WHEN r.CodePolice = '2' OR r.CodePolice = '4' THEN
                r.SommeReglementsFISDeduites * MAX(tc.ValeurF) / 100
END AS MttDec,
CASE
        WHEN r.CodePolice = '2' OR r.CodePolice = '4' THEN
                1.220
        WHEN r.CodePolice = '9' THEN
                MAX(ts.Valeur)
        ELSE
                CASE WHEN r.CodeFouE = 'F' THEN
                       MAX(tc.ValeurF)
                ELSE
                        MAX(tc.ValeurE)
                END
END AS TxRCP,
r.SommeReglementsFISDeduites * (
CASE
        WHEN r.CodePolice = '2' OR r.CodePolice = '4' THEN
                1.220
        WHEN r.CodePolice = '9' THEN
                MAX(ts.Valeur)
        ELSE
                CASE WHEN r.CodeFouE = 'F' THEN
                        MAX(tc.ValeurF)
                ELSE
                        MAX(tc.ValeurE)
                END
END) / 100 AS MontantRCP
FROM ASS_Reglements r
INNER JOIN ASS_CodeExerAffEnt c ON r.CodeExercice = c.CodeExercice AND r.CodeAffaire = c.CodeAffaire AND r.CodeEntite = c.CodeEntite
INNER JOIN ASS_Taux t ON c.CodePolice = t.CodePolice AND c.CodeExercice = t.CodeExercice
LEFT JOIN ASS_TauxClassique tc ON t.TauxID = tc.TauxID AND c.CodeEntite = tc.CodeEntite
LEFT JOIN ASS_TauxSpecifique ts ON t.TauxID = ts.TauxID AND c.CodeAffaire = ts.CodeAffaire
INNER JOIN ASS_CodePolice p ON t.CodePolice = p.CodePolice
GROUP BY r.CodeEntite, r.LibelleSociete, RIGHT(r.CodeAffaire,5), r.LibelleAffaire, r.GN, p.LibellePolice, c.CodeFouE, r.SommeReglementsFISDeduites, c.CodePolice, r.CodePolice, r.CodeFouE
ORDER BY r.CodeEntite, RIGHT(r.CodeAffaire,5)
Voici également les tables :



Et un extrait du résultat attendu :





Il y'a probablement un pb de jointure + un pb d'utilisation du MAX() mais si je retire les MAX() de ma requête je dois ajouter ces valeurs dans le GROUP BY et la requête retourne des lignes en doublon.

j'ai essayé différentes choses, en long en large en travers mais rien à faire.

Merci d'avance pour votre aide
Marco94 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/02/2011, 14h51   #2
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
Bonjour,

je ne sais pas ce que vous entendez par "assez longue", mais je pencherai plutôt pour un manque d'index...

qu'avez vous comme index sur les tables qui entrent en jeu dans votre requête ?

D'après votre schéma, vous ne semblez pas avoir défini toutes les contraintes d’intégrité referentielles... (par exemple entre ASS_Reglements et ASS_CodeExerAffEnt ) est-ce le cas ?

au passage, quel est votre SGBDR ?
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/02/2011, 15h26   #3
Invité de passage
 
Inscription : mai 2008
Messages : 14
Détails du profil
Informations forums :
Inscription : mai 2008
Messages : 14
Points : 2
Points : 2
Par "assez longue" j'entends que le traitement prend 20-25 sec.

Je n'ai pas d'index sur ces tables, je ne suis pas familier avec les index mais je vais creuser de ce coté là.

"contraintes d’intégrité referentielles" << je ne suis pas sur de comprendre, s'agit'il de contrainte de clés primaires/secondaires ?

Mon SGBDR est SQL Server 2000
Marco94 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/02/2011, 15h48   #4
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
Citation:
Envoyé par Marco94 Voir le message
Par "assez longue" j'entends que le traitement prend 20-25 sec.

Je n'ai pas d'index sur ces tables, je ne suis pas familier avec les index mais je vais creuser de ce coté là.
oui, je pense que c'est la première chose à faire

Citation:
"contraintes d’intégrité referentielles" << je ne suis pas sur de comprendre, s'agit'il de contrainte de clés primaires/secondaires ?
oui, et si elles n'y sont pas, c'est en fait ça la première chose à faire

Avez vous au final besoin de récupérer l'ensemble des résultats, ou comptez vous filtrer sur pour ne garder que certaines lignes ?

Une autre piste aussi :
Il semble que vous ayez des taux spécifiques pour certaines affaires, d'ou les jointures externes...
peut être pourriez vous prévoir deux requêtes avec UNION ALL, l'une pour les taux spécifiques :
Code sql :
WHERE r.codePolice = 9
l'autre pour les taux classiques :
Code sql :
WHERE r.codePolice <> 9

Ça fera une jointure interne a chaque fois au lieu de deux jointures externes
Vos CASES seraient en plus simplifiés...
mais c'est a tester, car il n'est pas sur que cela donnera de meilleurs perfs...
Et je ne suis pas certain non plus de ne pas avoir loupé qq chose dans la requete que vous avez postée. donc a vérifier, en comparant les temps/plan d’exécution des deux requêtes.
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 16h56.


 
 
 
 
Partenaires

Hébergement Web