Bonjour,
J'ai un problème de performance sur une requête. J'ai identifié pourquoi mais je n'arrive pas à le lever.
Voici une réduction de la requête de base
Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 Select toto, titi, tutu From TATAble T LEFT JOIN FonctionPrecedent(@Param1, @Param2) P ON T.ID = P.CdeTATAble LEFT JOIN FonctionSuivant(@Param3, @Param2) S ON T.ID = S.CdeTATAble
Mes fonctions plombent les performance car elles sont réexécutées autant de fois qu'il y a d'enregistrements, et comme il y en a beaucoup, je passe de 2 secondes sans les fonctions à 5 minutes avec.
Vu que c'est une procédure stockée appelée depuis l'application, j'ai essayé de passer par des tables temporaires en faisant :
Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 declare @Precedent (Champ1, ...); insert @Precedent select ... from FonctionPrecedent(@Param1, @Param2); declare @Suivant (Champ1, ...); insert @Suivant select ... from FonctionSuivant(@Param3, @Param2); Select toto, titi, tutu From TATAble T LEFT JOIN @Precedent P ON T.ID = P.CdeTATAble LEFT JOIN @Suivant S ON T.ID = S.CdeTATAble
Ca marche nickel, à nouveau 2 secondes pour avoir les résultats dans SQL Manager, seulement voilà, quand j'appelle cette procédure stockée depuis mon application, la procédure renvoie 0 pour dire que tout s'est bien passé... Et non le résultat de ma requête. Du coup je me pose la question de savoir si on peut renvoyer le résultat d'une requête même si dans la procédure stockée on fait d'autres chose ?
Bien sûr, il me faut régler ce problème de performance au plus vite.
Voici ma fonction :
Code sql : 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 CREATE FUNCTION dbo.fctGetNextLocks ( @bitDownStream BIT = NULL , @bitWithMe BIT = NULL , @tinQuantity TINYINT = NULL , @nvcLanguage typSmartCode = NULL ) RETURNS TABLE --WITH ENCRYPTION RETURN ( SELECT TOP (IIF(@bitDownStream IS NULL OR ISNULL(@tinQuantity, 0) = 0, (SELECT COUNT(*) FROM tblPlace), @tinQuantity)) T.nvcLabel Label , IIF(ISNULL(@bitDownStream, 0) = 0, 1, -1) * CAST(PV.varValue AS BIGINT) NumOrder , P.LID PlaceLID FROM tblPlace P INNER JOIN tblTranslation T ON P.CdeLabel = T.CdeLabel INNER JOIN tblLanguage L ON T.CdeLanguage = L.LID INNER JOIN tblPlaceType PT ON P.CdePlaceType = PT.LID INNER JOIN tblParameterValue PV ON PV.CdePlace = P.LID INNER JOIN tblParameterDefinition PD ON PV.CdeParameterDefinition = PD.LID WHERE PT.nvcSmartCode = N'Lck' AND PD.nvcSmartCode = N'PtKm' AND L.nvcSmartCode = IIF(ISNULL(@nvcLanguage, N'') = N'', dbo.fctGetActiveLanguage(), @nvcLanguage) AND P.nvcSmartCode <> IIF(ISNULL(@bitWithMe, 0) = 0, dbo.fctGetActiveSiteSmartCode(), N'') AND ( ( ISNULL(@bitDownStream, 0) = 0 AND PV.varValue >= dbo.fctGetActiveSiteParameterValue(N'PtKm') ) OR ( ISNULL(@bitDownStream, 1) = 1 AND PV.varValue <= dbo.fctGetActiveSiteParameterValue(N'PtKm') ) ) ORDER BY NumOrder )
Et voici ma procédure stockée avec le problème de performance :
Code sql : 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 CREATE PROCEDURE dbo.pcdGetBoatsPosition @bitAllBoat BIT = NULL --WITH ENCRYPTION AS BEGIN SELECT GB.BoatENICode , GB.BoatMMSICode , GB.BoatName , GB.BoatLength , GB.BoatLarge , GB.BoatIsADNR , GB.BoatComment , GB.BoatIsUpdatable , GB.BoatTypeLockKeeper , GB.BoatValidationState , GB.Country , GB.BoatComment , GB.BoatVersion , IIF(NLD.PlaceLID IS NULL, IIF(NLU.PlaceLID IS NULL, 0, -1), 1) ArrivalFrom , IIF(NLD.PlaceLID IS NULL AND NLU.PlaceLID IS NULL, NULL, ISNULL(MAX(L.dtoEnd), MAX(LT.dtoLockOut))) LastLockOut FROM dbo.fctGetBoats(1, 0, DEFAULT) GB LEFT JOIN tblJourney J ON J.CdeBoat = GB.BoatLID LEFT JOIN tblGarage G ON G.CdeJourney = J.LID LEFT JOIN dbo.fctGetNextLocks(0, 0, 1, DEFAULT) NLD ON G.CdePlace = NLD.PlaceLID AND J.CdePlace_LastLock <> NLD.PlaceLID LEFT JOIN dbo.fctGetNextLocks(0, 0, 1, DEFAULT) NLU ON G.CdePlace = NLU.PlaceLID AND J.CdePlace_LastLock <> NLU.PlaceLID LEFT JOIN tblLockTransit LT ON LT.CdeGarage = G.LID LEFT JOIN tblLockage L ON LT.CdeLockage = L.LID GROUP BY GB.BoatENICode , GB.BoatMMSICode , GB.BoatName , GB.BoatLength , GB.BoatLarge , GB.BoatIsADNR , GB.BoatComment , GB.BoatIsUpdatable , GB.BoatTypeLockKeeper , GB.BoatValidationState , GB.Country , GB.BoatComment , GB.BoatVersion , NLD.PlaceLID , NLU.PlaceLID ORDER BY BoatENICode , BoatVersion
Et ma procédure modifiée :
Code sql : 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 CREATE PROCEDURE dbo.pcdGetBoatsPosition @bitAllBoat BIT = NULL --WITH ENCRYPTION AS BEGIN DECLARE @NextLockDown TABLE ( Label typLabel , NumOrder INT , PlaceLID typLID); INSERT INTO @NextLockDown SELECT Label , NumOrder , PlaceLID FROM dbo.fctGetNextLocks(0, 0, 1, DEFAULT); DECLARE @NextLockUp TABLE ( Label typLabel , NumOrder INT , PlaceLID typLID); INSERT INTO @NextLockUp SELECT Label , NumOrder , PlaceLID FROM dbo.fctGetNextLocks(1, 0, 1, DEFAULT); SELECT GB.BoatENICode , GB.BoatMMSICode , GB.BoatName , GB.BoatLength , GB.BoatLarge , GB.BoatIsADNR , GB.BoatComment , GB.BoatIsUpdatable , GB.BoatTypeLockKeeper , GB.BoatValidationState , GB.Country , GB.BoatComment , GB.BoatVersion , IIF(NLD.PlaceLID IS NULL, IIF(NLU.PlaceLID IS NULL, 0, -1), 1) ArrivalFrom , IIF(NLD.PlaceLID IS NULL AND NLU.PlaceLID IS NULL, NULL, ISNULL(MAX(L.dtoEnd), MAX(LT.dtoLockOut))) LastLockOut FROM dbo.fctGetBoats(1, 0, DEFAULT) GB LEFT JOIN tblJourney J ON J.CdeBoat = GB.BoatLID LEFT JOIN tblGarage G ON G.CdeJourney = J.LID LEFT JOIN @NextLockDown NLD ON G.CdePlace = NLD.PlaceLID AND J.CdePlace_LastLock <> NLD.PlaceLID LEFT JOIN @NextLockUp NLU ON G.CdePlace = NLU.PlaceLID AND J.CdePlace_LastLock <> NLU.PlaceLID LEFT JOIN tblLockTransit LT ON LT.CdeGarage = G.LID LEFT JOIN tblLockage L ON LT.CdeLockage = L.LID GROUP BY GB.BoatENICode , GB.BoatMMSICode , GB.BoatName , GB.BoatLength , GB.BoatLarge , GB.BoatIsADNR , GB.BoatComment , GB.BoatIsUpdatable , GB.BoatTypeLockKeeper , GB.BoatValidationState , GB.Country , GB.BoatComment , GB.BoatVersion , NLD.PlaceLID , NLU.PlaceLID ORDER BY BoatENICode , BoatVersion
Si vous avez des idées, je prends.
Merci à vous.
Partager