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.