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

Développement SQL Server Discussion :

Problème de performance


Sujet :

Développement SQL Server

  1. #1
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2010
    Messages
    185
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2010
    Messages : 185
    Points : 167
    Points
    167
    Par défaut Problème de performance
    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.

  2. #2
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    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 136
    Points : 38 910
    Points
    38 910
    Billets dans le blog
    9
    Par défaut
    Beaucoup de choses dans vos filtres :
    - vous avez des prédicats différent, non sargables
    - vous avez des OR, même combat
    - vous utilisez des fonctions de colonne

    - A vérifier aussi dans votre DDL, vos colonnes de jointure et de filtre sont elles bien de même type et de même longueur ?
    - Y a -t-il des index éligibles pour vos filtres et vos jointures ?

    Remplacez vos ISNULL de jointure ou filtrage par COALESCE

  3. #3
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Bonjour,

    il serait intéressant d'avoir aussi le code des autres fonctions utilisées.

    Pour la fonction que vous avez présentée, il s'agit d'une fonction table en ligne ce qui est très bien (bien mieux qu'une fonction multi-instructions). En revanche, avec le TOP et le GROUP BY, cela risque quand même de pénaliser

    Avoir le plan d’exécution serait très utile pour vous aider !



    Citation Envoyé par escartefigue Voir le message
    Remplacez vos ISNULL de jointure ou filtrage par COALESCE
    pas sûr, surtout celles faisant appel aux fonctions, qui, je suppose, font également des requêtes.

  4. #4
    Expert éminent
    Avatar de Lyche
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2007
    Messages
    2 523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 523
    Points : 6 775
    Points
    6 775
    Billets dans le blog
    4
    Par défaut
    si ma mémoire est bonne, il me semble que le OUTER APPLY est très efficace pour les problèmes de perfs dans l'utilisation de fonction tables.

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT *
      FROM maTable
          OUTER APPLY ( SELECT * FROM dbo.maFonctionTable( champ_filtre ) ) AS Fct;
    Rejoignez la communauté du chat et partagez vos connaissances ou vos questions avec nous

    Mon Tutoriel pour apprendre les Agregations
    Consultez mon Blog SQL destiné aux débutants

    Pensez à FAQ SQL Server Ainsi qu'aux Cours et Tuto SQL Server

  5. #5
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2010
    Messages
    185
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2010
    Messages : 185
    Points : 167
    Points
    167
    Par défaut
    Citation Envoyé par escartefigue Voir le message
    Beaucoup de choses dans vos filtres :
    - vous avez des prédicats différent, non sargables
    - vous avez des OR, même combat
    - vous utilisez des fonctions de colonne

    - A vérifier aussi dans votre DDL, vos colonnes de jointure et de filtre sont elles bien de même type et de même longueur ?
    - Y a -t-il des index éligibles pour vos filtres et vos jointures ?

    Remplacez vos ISNULL de jointure ou filtrage par COALESCE
    Toutes mes colonnes de jointures sont typés de façon identique (grâce aux déclarations de type) et toutes les jointures sont indexées. Pour les filtres non.

    Il y a une différence entre ISNULL et COALESCE ???

  6. #6
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2010
    Messages
    185
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2010
    Messages : 185
    Points : 167
    Points
    167
    Par défaut
    Citation Envoyé par aieeeuuuuu Voir le message
    Bonjour,

    il serait intéressant d'avoir aussi le code des autres fonctions utilisées.

    Pour la fonction que vous avez présentée, il s'agit d'une fonction table en ligne ce qui est très bien (bien mieux qu'une fonction multi-instructions). En revanche, avec le TOP et le GROUP BY, cela risque quand même de pénaliser

    Avoir le plan d’exécution serait très utile pour vous aider !




    pas sûr, surtout celles faisant appel aux fonctions, qui, je suppose, font également des requêtes.


    Les autres fonctions sont basées sur des requêtes pour retourner une valeur.

    Les voici :
    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
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
     
    CREATE FUNCTION [dbo].[fctGetActiveLanguage]()
    RETURNS CHAR(2)
    --WITH ENCRYPTION
    BEGIN
    	DECLARE	@chrValue CHAR(2);	-- Valeur du paramètre à retourner
     
    	-- Chercher la valeur du paramètre du site
    	SET @chrValue = CAST(dbo.fctGetActiveSiteParameterValue(N'ActivLang') AS CHAR(2));
     
    	-- Si la valeur est null ou que la taille est nulle alors renvoyer une erreur
    	IF ISNULL(@chrValue, N'') = N'' SET @chrValue = NULL;
     
    	RETURN @chrValue;
    END
     
    CREATE FUNCTION [dbo].[fctGetActiveSiteParameterValue]
    (
    	@nvcParameterSmartCode typSmartCode = NULL
    )
    RETURNS typParameterValue
    --WITH ENCRYPTION
    BEGIN
    	RETURN dbo.fctGetParameterValue(@nvcParameterSmartCode, DEFAULT);
    END
     
    CREATE FUNCTION [dbo].[fctGetParameterValue]
    (
    	@nvcParameterSmartCode	typSmartCode	= NULL
    ,	@nvcPlaceSmartCode		typSmartCode	= NULL
    )
    RETURNS typParameterValue
    --WITH ENCRYPTION
    BEGIN
    DECLARE	@tinLevelUp TINYINT;					-- Niveau du lieu
    DECLARE	@nvcActiveSiteSmartCode typSmartCode;	-- Lieu courant
    DECLARE	@varPlaceSmartCode typParameterValue;	-- Lieu récupéré
    DECLARE	@varValue typParameterValue;			-- Valeur du paramètre à retourner
     
    	-- Chercher le site actif
    	SELECT
    	   TOP	1
    			@nvcActiveSiteSmartCode = CAST(PV.varValue AS NVARCHAR(MAX))
    	  FROM	tblParameterDefinition PD
    				INNER JOIN	tblParameterValue PV
    						ON	PV.CdeParameterDefinition = PD.LID
    	 WHERE	LOWER(PD.nvcSmartCode) = LOWER(N'ActivPlcSC')
    	   AND	PV.bitIsActivated <> 0
    	 ORDER
    		BY	PV.dtoCreatedDate;
     
     	-- Chercher la valeur du paramètre
    	IF ISNULL(@nvcPlaceSmartCode, N'') = N''
    		SET @varPlaceSmartCode = @nvcActiveSiteSmartCode;
    	ELSE
    		IF EXISTS(SELECT	1
    					FROM	dbo.fctGetHierarchyPlace(DEFAULT, @nvcActiveSiteSmartCode, DEFAULT, DEFAULT, DEFAULT)
    				   WHERE	nvcSmartCode = @nvcPlaceSmartCode) OR dbo.fctGetActiveSiteLID() = 0
    			SET @varPlaceSmartCode = @nvcPlaceSmartCode;
     
    	IF ISNULL(@varPlaceSmartCode, N'') <> N''
    		IF ISNULL(@nvcParameterSmartCode, N'') = N'' OR LOWER(@nvcParameterSmartCode) = LOWER(N'ActivPlcSC')
    			SET @varValue = @varPlaceSmartCode;
    		ELSE
    			SELECT
    			   TOP	1
    					@varValue = PV.varValue
    			  FROM	dbo.fctGetHierarchyPlace(DEFAULT, CAST(@varPlaceSmartCode AS NVARCHAR(MAX)), 1, DEFAULT, DEFAULT) RQP
    						INNER JOIN	tblParameterValue PV
    								ON	PV.CdePlace = RQP.LID
    						INNER JOIN tblParameterDefinition PD
    								ON	PV.CdeParameterDefinition = PD.LID
    			 WHERE	LOWER(PD.nvcSmartCode) = LOWER(@nvcParameterSmartCode)
    			   AND	PV.bitIsActivated <> 0
    			 ORDER
    				BY	DepthLevel;
     
    	-- Si la valeur est null ou que la taille est nulle alors renvoyer une chaine vide
    	IF ISNULL(@varValue, N'') = N'' SET @varValue = NULL;
     
    	RETURN @varValue;
    END
     
    CREATE FUNCTION [dbo].[fctGetHierarchyPlace]
    (
    	@LIDPlace						typLID			= NULL
    ,	@nvcSmartCode					typSmartCode	= NULL
    ,	@bitGoToTrunk					BIT				= NULL
    ,	@bytDepth						TINYINT			= NULL
    ,	@bitAll							BIT				= NULL
    )
    RETURNS	TABLE
    --WITH ENCRYPTION
    RETURN
    (
    	WITH RecursiveQuery_Place
    		-- Définition de la structure de la table opérant la récursivité
    		AS (-- Requête de départ
    			SELECT
    					P.LID
    				 ,	P.GID
    				 ,	P.nvcSmartCode
    				 ,	P.CdeLabel
    				 ,	P.CdePlaceType
    				 ,	P.CdePlace_Parent
    				 ,	P.nvcCodeSIFRS
    				 ,	P.bitIsActivated
    				 ,	P.bitIsActivated				IsActivatedCascade
    				 ,	0								DepthLevel
    				 ,	CAST(P.LID AS NVARCHAR(MAX))	CompletPath
    			  FROM	tblPlace P
    			-- Condition sur la requête de base
    			 WHERE	(@nvcSmartCode IS NULL AND P.LID = ISNULL(@LIDPlace, dbo.fctGetActiveSiteLID()))
    				OR	(@LIDPlace IS NULL AND P.nvcSmartCode = ISNULL(@nvcSmartCode, dbo.fctGetActiveSiteSmartCode()))
    				OR	(P.LID = @LIDPlace AND P.nvcSmartCode = @nvcSmartCode)
    			UNION ALL
    			-- Requête de récursion
    			SELECT
    					P.LID
    				 ,	P.GID
    				 ,	P.nvcSmartCode
    				 ,	P.CdeLabel
    				 ,	P.CdePlaceType
    				 ,	P.CdePlace_Parent
    				 ,	P.nvcCodeSIFRS
    				 ,	P.bitIsActivated
    				 ,	CAST(IIF(P.bitIsActivated <> 0 AND RQP.IsActivatedCascade <> 0, 1, 0) AS BIT)
    				 ,	RQP.DepthLevel + 1
    				 ,	RQP.CompletPath + N'-' + CAST(P.LID AS NVARCHAR(MAX))
    			  FROM	tblPlace P
    			-- Lien avec la récursion
    						INNER JOIN	RecursiveQuery_Place RQP
    								ON	IIF(ISNULL(@bitGoToTrunk, 0) = 0, P.CdePlace_Parent	, RQP.CdePlace_Parent) =
    									IIF(ISNULL(@bitGoToTrunk, 0) = 0, RQP.LID			, P.LID)
    			 WHERE	RQP.DepthLevel < ISNULL(IIF(@bytDepth < 100, @bytDepth, 100), 100)
    			)
    		SELECT
    				RQP.LID
    			 ,	RQP.GID
    			 ,	RQP.nvcSmartCode
    			 ,	RQP.CdeLabel
    			 ,	RQP.CdePlaceType
    			 ,	RQP.CdePlace_Parent
    			 ,	RQP.nvcCodeSIFRS
    			 ,	RQP.IsActivatedCascade
    			 ,	RQP.DepthLevel
    			 ,	RQP.CompletPath
    		  FROM	RecursiveQuery_Place RQP
    		 WHERE	IIF(ISNULL(@bitAll, 0) = 0, RQP.IsActivatedCascade, 1) <> 0
    )
     
    CREATE FUNCTION [dbo].[fctGetActiveSiteLID]()
    RETURNS typLID
    --WITH ENCRYPTION
    BEGIN
    	DECLARE	@LIDPlace			typLID;			-- Valeur du paramètre à retourner
    	DECLARE	@nvcSiteSmartCode	typSmartCode;	-- SmartCode du site actif
     
    	SET @nvcSiteSmartCode = dbo.fctGetActiveSiteSmartCode();
     
    	-- Chercher LID du site
    	SELECT	@LIDPlace = LID
    	  FROM	tblPlace
    	 WHERE	nvcSmartCode = @nvcSiteSmartCode;
     
    	RETURN @LIDPlace;
    END
     
    CREATE FUNCTION [dbo].[fctGetActiveSiteSmartCode]()
    RETURNS typSmartCode
    --WITH ENCRYPTION
    BEGIN
    	DECLARE	@chrValue typSmartCode;	-- Valeur du paramètre à retourner
     
    	-- Chercher la valeur du paramètre du site
    	SET @chrValue = CAST(dbo.fctGetActiveSiteParameterValue(DEFAULT) AS CHAR(3));
     
    	-- Si la valeur est null ou que la taille est nulle alors renvoyer une erreur
    	IF ISNULL(@chrValue, N'') = N'' SET @chrValue = NULL;
     
    	RETURN @chrValue;
    END
     
    CREATE FUNCTION dbo.fctGetBoats
    (
    	@bitAllBoat		BIT = NULL
    ,	@bitAllVersion	BIT = NULL
    ,	@nvcENICode		typENICode = NULL
    )
    RETURNS TABLE
    --WITH ENCRYPTION
    RETURN
    (
    	WITH RecursiveQuery_Boat
    		AS
    			(
    			SELECT
    					B.LID
    				 ,	B.GID
    				 ,	B.nvcENICode
    				 ,	B.nvcMMSICode
    				 ,	B.nvcRegistration
    				 ,	B.nvcName
    				 ,	B.decBuildYear
    				 ,	B.decLength
    				 ,	B.decLarge
    				 ,	B.decAirDraughtEmpty
    				 ,	B.decAirDraughtBallasted
    				 ,	B.decDraught
    				 ,	B.decMaxWeight
    				 ,	B.decNbEngines
    				 ,	B.decPowerEngine
    				 ,	B.decNbTanks
    				 ,	B.decNbHolds
    				 ,	B.decNbPassengers
    				 ,	B.nvcHomePort
    				 ,	B.bitIsADNR
    				 ,	B.nvcPhone
    				 ,	B.nvcFax
    				 ,	B.nvcIMOCode
    				 ,	B.bitIsUpdatable
    				 ,	B.CdeBoat_Parent
    				 ,	B.CdeBoatCategory
    				 ,	B.CdeBoatGoodsType
    				 ,	B.CdeBoatTypeSIFRS
    				 ,	B.CdeBoatTypeLockKeeper
    				 ,	B.CdeBoatUsing
    				 ,	B.CdeBoatValidationState
    				 ,	B.CdeCountry
    				 ,	B.CdeOriginData
    				 ,	B.nvcComment
    				 ,	B.bitIsActivated
    				 ,	B.bitIsValidated
    				 ,	B.bitIsTransmitted
    				 ,	B.dtoCreatedDate
    				 ,	B.CdeCreatedPlace
    				 ,	B.CdeCreatedUser
    				 ,	B.dtoUpdatedDate
    				 ,	B.CdeUpdatedPlace
    				 ,	B.CdeUpdatedUser
    				 ,	0							BoatVersion
    			  FROM	tblBoat B
    			 WHERE	B.CdeBoat_Parent IS NULL
    			   AND	B.nvcENICode = IIF(ISNULL(@nvcENICode, N'') = N'', B.nvcENICode, @nvcENICode)
    			UNION ALL
    			SELECT
    					B.LID
    				 ,	B.GID
    				 ,	B.nvcENICode
    				 ,	B.nvcMMSICode
    				 ,	B.nvcRegistration
    				 ,	B.nvcName
    				 ,	B.decBuildYear
    				 ,	B.decLength
    				 ,	B.decLarge
    				 ,	B.decAirDraughtEmpty
    				 ,	B.decAirDraughtBallasted
    				 ,	B.decDraught
    				 ,	B.decMaxWeight
    				 ,	B.decNbEngines
    				 ,	B.decPowerEngine
    				 ,	B.decNbTanks
    				 ,	B.decNbHolds
    				 ,	B.decNbPassengers
    				 ,	B.nvcHomePort
    				 ,	B.bitIsADNR
    				 ,	B.nvcPhone
    				 ,	B.nvcFax
    				 ,	B.nvcIMOCode
    				 ,	B.bitIsUpdatable
    				 ,	B.CdeBoat_Parent
    				 ,	B.CdeBoatCategory
    				 ,	B.CdeBoatGoodsType
    				 ,	B.CdeBoatTypeSIFRS
    				 ,	B.CdeBoatTypeLockKeeper
    				 ,	B.CdeBoatUsing
    				 ,	B.CdeBoatValidationState
    				 ,	B.CdeCountry
    				 ,	B.CdeOriginData
    				 ,	B.nvcComment
    				 ,	B.bitIsActivated
    				 ,	B.bitIsValidated
    				 ,	B.bitIsTransmitted
    				 ,	B.dtoCreatedDate
    				 ,	B.CdeCreatedPlace
    				 ,	B.CdeCreatedUser
    				 ,	B.dtoUpdatedDate
    				 ,	B.CdeUpdatedPlace
    				 ,	B.CdeUpdatedUser
    				 ,	RQB.BoatVersion + 1
    			  FROM	tblBoat B
    						INNER JOIN	RecursiveQuery_Boat RQB
    								ON	RQB.LID = B.CdeBoat_Parent
    			)
    	SELECT
    			RQB.LID						BoatLID
    		 ,	RQB.GID						BoatGID
    		 ,	RQB.nvcENICode				BoatENICode
    		 ,	RQB.nvcMMSICode				BoatMMSICode
    		 ,	RQB.nvcRegistration			BoatRegistration
    		 ,	RQB.nvcName					BoatName
    		 ,	RQB.decBuildYear			BoatBuildYear
    		 ,	RQB.decLength				BoatLength
    		 ,	RQB.decLarge				BoatLarge
    		 ,	RQB.decAirDraughtEmpty		BoatAirDraughtEmpty
    		 ,	RQB.decAirDraughtBallasted	BoatAirDraughtBallasted
    		 ,	RQB.decDraught				BoatDraught
    		 ,	RQB.decMaxWeight			BoatMaxWeight
    		 ,	RQB.decNbEngines			BoatNbEngines
    		 ,	RQB.decPowerEngine			BoatPowerEngine
    		 ,	RQB.decNbTanks				BoatNbTanks
    		 ,	RQB.decNbHolds				BoatNbHolds
    		 ,	RQB.decNbPassengers			BoatNbPassengers
    		 ,	RQB.nvcHomePort				BoatHomePort
    		 ,	RQB.bitIsADNR				BoatIsADNR
    		 ,	RQB.nvcPhone				BoatPhone
    		 ,	RQB.nvcFax					BoatFax
    		 ,	RQB.nvcIMOCode				BoatIMOCode
    		 ,	RQB.bitIsUpdatable			BoatIsUpdatable
    		 ,	RQB.CdeBoat_Parent			BoatLIDParent
    		 ,	BC.nvcSmartCode				BoatCategory
    		 ,	BGT.nvcSmartCode			BoatGoodsType
    		 ,	BTS.nvcSmartCode			BoatTypeSIFRS
    		 ,	BTLK.nvcSmartCode			BoatTypeLockKeeper
    		 ,	BU.nvcSmartCode				BoatUsing
    		 ,	BVS.nvcSmartCode			BoatValidationState
    		 ,	C.chrCodeISO3166Alpha2		Country
    		 ,	OD.nvcSmartCode				OriginData
    		 ,	RQB.nvcComment				BoatComment
    		 ,	RQB.bitIsActivated			BoatIsActivated
    		 ,	RQB.bitIsValidated			BoatIsValidated
    		 ,	RQB.bitIsTransmitted		BoatIsTransmitted
    		 ,	RQB.dtoCreatedDate			BoatCreatedDate
    		 ,	RQB.CdeCreatedPlace			BoatCreatedPlace
    		 ,	RQB.CdeCreatedUser			BoatCreatedUser
    		 ,	RQB.dtoUpdatedDate			BoatLastUpdatedDate
    		 ,	RQB.CdeUpdatedPlace			BoatLastUpdatedPlace
    		 ,	RQB.CdeUpdatedUser			BoatLastUpdatedUser
    		 ,	RQB.BoatVersion				BoatVersion
    	  FROM	RecursiveQuery_Boat RQB
    				INNER JOIN tblBoatCategory BC
    						ON RQB.CdeBoatCategory = BC.LID
    				INNER JOIN tblBoatGoodsType BGT
    						ON RQB.CdeBoatGoodsType = BGT.LID
    				INNER JOIN tblBoatTypeLockKeeper BTLK
    						ON RQB.CdeBoatTypeLockKeeper = BTLK.LID
    				INNER JOIN tblBoatTypeSIFRS BTS
    						ON RQB.CdeBoatTypeSIFRS = BTS.LID
    				INNER JOIN tblBoatUsing BU
    						ON RQB.CdeBoatUsing = BU.LID
    				INNER JOIN tblBoatValidationState BVS
    						ON RQB.CdeBoatValidationState = BVS.LID
    				INNER JOIN tblCountry C
    						ON RQB.CdeCountry = C.LID
    				INNER JOIN tblOriginData OD
    						ON RQB.CdeOriginData = OD.LID
    	 WHERE	(RQB.bitIsActivated <> 0 OR @bitAllVersion <> 0)
    	   AND	RQB.dtoUpdatedDate >= IIF(ISNULL(@bitAllBoat, 0) = 0,
    									  dbo.fctGetParameterValue(N'PrevUpdate', DEFAULT),
    									  RQB.dtoUpdatedDate)
    )

    Je crois que je n'ai rien oublié

  7. #7
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2010
    Messages
    185
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2010
    Messages : 185
    Points : 167
    Points
    167
    Par défaut
    Citation Envoyé par Lyche Voir le message
    si ma mémoire est bonne, il me semble que le OUTER APPLY est très efficace pour les problèmes de perfs dans l'utilisation de fonction tables.

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT *
      FROM maTable
          OUTER APPLY ( SELECT * FROM dbo.maFonctionTable( champ_filtre ) ) AS Fct;
    Je viens d'essayer et le temps de réponse est sensiblement identique, 4'52'' au lieu de 5'12''... Mais je ne connaissais pas cette solution et me renseignerais sur son utilité

Discussions similaires

  1. Problème de performance avec LEFT OUTER JOIN
    Par jgfa9 dans le forum Requêtes
    Réponses: 6
    Dernier message: 17/07/2005, 13h17
  2. [jeu]problème de performance d'un algo
    Par le Daoud dans le forum Algorithmes et structures de données
    Réponses: 12
    Dernier message: 30/05/2005, 16h07
  3. [C#] Probléme de performance avec IsDbNull
    Par jab dans le forum Windows Forms
    Réponses: 8
    Dernier message: 04/04/2005, 11h39
  4. [oracle 9i][Workbench]Problème de performance
    Par nuke_y dans le forum Oracle
    Réponses: 6
    Dernier message: 03/02/2005, 17h38
  5. [ POSTGRESQL ] Problème de performance
    Par Djouls64 dans le forum PostgreSQL
    Réponses: 6
    Dernier message: 26/05/2003, 16h18

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