J'ai une requête SQL que j'ai passé les deux derniers jours à essayer d'optimiser à l'aide d'essais et d'erreurs et du plan d'exécution, mais en vain. Veuillez me pardonner de le faire, mais je publierai le plan d'exécution complet ici. J'ai fait l'effort de rendre les noms de table et de colonne dans le plan de requête et d'exécution génériques à la fois pour la brièveté et pour protéger l'IP de mon entreprise. Le plan d'exécution peut être ouvert avec SQL Sentry Plan Explorer .
J'ai fait pas mal de T-SQL, mais l'utilisation de plans d'exécution pour optimiser ma requête est un nouveau domaine pour moi et j'ai vraiment essayé de comprendre comment le faire. Donc, si quelqu'un pouvait m'aider avec cela et expliquer comment ce plan d'exécution peut être déchiffré pour trouver des moyens dans la requête pour l'optimiser, je serais éternellement reconnaissant. J'ai beaucoup plus de requêtes à optimiser - j'ai juste besoin d'un tremplin pour m'aider avec cette première.
Voici la requête:
DECLARE @Param0 DATETIME = '2013-07-29';
DECLARE @Param1 INT = CONVERT(INT, CONVERT(VARCHAR, @Param0, 112))
DECLARE @Param2 VARCHAR(50) = 'ABC';
DECLARE @Param3 VARCHAR(100) = 'DEF';
DECLARE @Param4 VARCHAR(50) = 'XYZ';
DECLARE @Param5 VARCHAR(100) = NULL;
DECLARE @Param6 VARCHAR(50) = 'Text3';
SET NOCOUNT ON
DECLARE @MyTableVar TABLE
(
B_Var1_PK int,
Job_Var1 varchar(512),
Job_Var2 varchar(50)
)
INSERT INTO @MyTableVar (B_Var1_PK, Job_Var1, Job_Var2)
SELECT B_Var1_PK, Job_Var1, Job_Var2 FROM [fn_GetJobs] (@Param1, @Param2, @Param3, @Param4, @Param6);
CREATE TABLE #TempTable
(
TTVar1_PK INT PRIMARY KEY,
TTVar2_LK VARCHAR(100),
TTVar3_LK VARCHAR(50),
TTVar4_LK INT,
TTVar5 VARCHAR(20)
);
INSERT INTO #TempTable
SELECT DISTINCT
T.T1_PK,
T.T1_Var1_LK,
T.T1_Var2_LK,
MAX(T.T1_Var3_LK),
T.T1_Var4_LK
FROM
MyTable1 T
INNER JOIN feeds.MyTable2 A ON A.T2_Var1 = T.T1_Var4_LK
INNER JOIN @MyTableVar B ON B.Job_Var2 = A.T2_Var2 AND B.Job_Var1 = A.T2_Var3
GROUP BY T.T1_PK, T.T1_Var1_LK, T.T1_Var2_LK, T.T1_Var4_LK
-- This is the slow statement...
SELECT
CASE E.E_Var1_LK
WHEN 'Text1' THEN T.TTVar2_LK + '_' + F.F_Var1
WHEN 'Text2' THEN T.TTVar2_LK + '_' + F.F_Var2
WHEN 'Text3' THEN T.TTVar2_LK
END,
T.TTVar4_LK,
T.TTVar3_LK,
CASE E.E_Var1_LK
WHEN 'Text1' THEN F.F_Var1
WHEN 'Text2' THEN F.F_Var2
WHEN 'Text3' THEN T.TTVar5
END,
A.A_Var3_FK_LK,
C.C_Var1_PK,
SUM(CONVERT(DECIMAL(18,4), A.A_Var1) + CONVERT(DECIMAL(18,4), A.A_Var2))
FROM #TempTable T
INNER JOIN TableA (NOLOCK) A ON A.A_Var4_FK_LK = T.TTVar1_PK
INNER JOIN @MyTableVar B ON B.B_Var1_PK = A.Job
INNER JOIN TableC (NOLOCK) C ON C.C_Var2_PK = A.A_Var5_FK_LK
INNER JOIN TableD (NOLOCK) D ON D.D_Var1_PK = A.A_Var6_FK_LK
INNER JOIN TableE (NOLOCK) E ON E.E_Var1_PK = A.A_Var7_FK_LK
LEFT OUTER JOIN feeds.TableF (NOLOCK) F ON F.F_Var1 = T.TTVar5
WHERE A.A_Var8_FK_LK = @Param1
GROUP BY
CASE E.E_Var1_LK
WHEN 'Text1' THEN T.TTVar2_LK + '_' + F.F_Var1
WHEN 'Text2' THEN T.TTVar2_LK + '_' + F.F_Var2
WHEN 'Text3' THEN T.TTVar2_LK
END,
T.TTVar4_LK,
T.TTVar3_LK,
CASE E.E_Var1_LK
WHEN 'Text1' THEN F.F_Var1
WHEN 'Text2' THEN F.F_Var2
WHEN 'Text3' THEN T.TTVar5
END,
A.A_Var3_FK_LK,
C.C_Var1_PK
IF OBJECT_ID(N'tempdb..#TempTable') IS NOT NULL
BEGIN
DROP TABLE #TempTable
END
IF OBJECT_ID(N'tempdb..#TempTable') IS NOT NULL
BEGIN
DROP TABLE #TempTable
END
Ce que j'ai trouvé, c'est que la troisième déclaration (commentée comme étant lente) est la partie qui prend le plus de temps. Les deux déclarations avant de revenir presque instantanément.
Le plan d'exécution est disponible en XML sur ce lien .
Mieux vaut cliquer avec le bouton droit et enregistrer, puis ouvrir dans SQL Sentry Plan Explorer ou un autre logiciel de visualisation plutôt que de l'ouvrir dans votre navigateur.
Si vous avez besoin de plus d'informations de ma part sur les tableaux ou les données, n'hésitez pas à demander.
tempdb
. c'est-à-dire les estimations pour les lignes résultant de la jointure entre TableA
et @MyTableVar
sont très éloignées. De plus, le nombre de lignes entrant dans les tris est beaucoup plus élevé que prévu, de sorte qu'elles pourraient également se répandre.