Bonjour,
Je révise le code d'un développeur junior et je vois cette fonction:
Je me dis, plutôt que de lancer 2 requêtes et placer des valeurs en mémoire, je vais faire un seule et unique requête:
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 ALTER FUNCTION [dbo].[RM_GetAvgDaysToPay] ( -- Add the parameters for the function here @CompanyID int ) RETURNS float AS BEGIN -- Declare the return variable here DECLARE @AvgDaysToPay float -- Add the T-SQL statements to compute the return value here DECLARE @Ansonia float DECLARE @Freight float SET @Ansonia = (SELECT TOP(1) aci.AvgDaysToPay FROM AnsoniaCreditInfo aci INNER JOIN CompanyDocketNumbers cdn ON aci.DocketPrefix = cdn.Prefix AND aci.DocketNumber = cdn.DocketNumber WHERE cdn.CompanyID = @CompanyID AND cdn.Purpose IN (1,3) ORDER BY cdn.Purpose) SET @Freight = (SELECT TOP(1) ci.AvgDaysToPay FROM CreditInformation ci INNER JOIN CompanyDocketNumbers cdn ON ci.DocketPrefix = cdn.Prefix AND ci.DocketNumber = cdn.DocketNumber WHERE cdn.CompanyID = @CompanyID AND ci.DocketNumber IS NOT NULL AND ci.DocketPrefix IS NOT NULL AND cdn.Purpose IN (1,3) ORDER BY cdn.Purpose) SET @AvgDaysToPay = CASE WHEN @Ansonia IS NULL AND @Freight IS NULL THEN NULL WHEN @Ansonia IS NOT NULL AND @Freight IS NOT NULL THEN CONVERT(float,(@Ansonia + @Freight)) / 2 WHEN @Ansonia IS NOT NULL THEN @Ansonia WHEN @Freight IS NOT NULL THEN @Freight END -- Return the result of the function RETURN @AvgDaysToPay END
Je lance les fonctions côte-à-côte en utilisant les bon vieux:
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 ALTER FUNCTION [dbo].[RM_GetAvgDaysToPay2] ( -- Add the parameters for the function here @CompanyID int ) RETURNS float AS BEGIN RETURN ( SELECT TOP 1 CASE WHEN aci.AvgDaysToPay IS NULL OR ci.AvgDaysToPay IS NULL THEN (ISNULL(aci.AvgDaysToPay, 0) + ISNULL(ci.AvgDaysToPay, 0)) ELSE (aci.AvgDaysToPay + ci.AvgDaysToPay) / 2 END AS AvgValue FROM CompanyDocketNumbers cdn LEFT JOIN AnsoniaCreditInfo aci ON cdn.DocketNumber = aci.DocketNumber AND cdn.Prefix = aci.DocketPrefix LEFT JOIN CreditInformation ci ON cdn.DocketNumber = ci.DocketNumber AND cdn.Prefix = ci.DocketPrefix WHERE cdn.CompanyID = @CompanyID AND cdn.Purpose IN (1,3) ORDER BY cdn.Purpose) END
1 - Les deux plans d'exécution sont identiques
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 SET STATISTICS IO ON SET STATISTICS TIME ON
2 - Les statistiques de TIME et IO sont à toute fin pratique semblables
Mon environnement:
Instance SQL Server 2008R2
Base en mode 90 (2005)
Ma question:
Est-ce que SQL Server arrive à optimiser le code des fonctions (et procédure stockées) à un point tel qu'il peut joindre deux requêtes distinctes en une seule?
Ou bien c'est mon optimisation 'manuelle' qui n'est pas bonne?
Je travaille avec MSSQL depuis la version 7 et j'ai peut-être des habitudes d'optmisation qui sont devenue superflues depuis.
Merci de m'éclairer à ce sujet.
Aussi, si vous avez des sources intéressantes sur la façon sont MSSQL compile les fonctions et l'évolution de ce processus depuis la version 7, j'apprécierais énormément.
Partager