Ich habe eine SQL-Abfrage, die ich in den letzten zwei Tagen versucht habe, mithilfe von Trial-and-Error und des Ausführungsplans zu optimieren, aber ohne Erfolg. Bitte verzeihen Sie mir, aber ich werde den gesamten Ausführungsplan hier veröffentlichen. Ich habe mich bemüht, die Tabellen- und Spaltennamen im Abfrage- und Ausführungsplan sowohl aus Gründen der Kürze als auch zum Schutz der IP-Adresse meines Unternehmens generisch zu gestalten. Der Ausführungsplan kann mit dem SQL Sentry Plan Explorer geöffnet werden .
Ich habe viel mit T-SQL gearbeitet, aber die Verwendung von Ausführungsplänen zur Optimierung meiner Abfrage ist für mich ein neuer Bereich, und ich habe wirklich versucht, zu verstehen, wie das geht. Wenn mir jemand dabei helfen und erklären könnte, wie dieser Ausführungsplan entschlüsselt werden kann, um in der Abfrage Möglichkeiten zu finden, ihn zu optimieren, wäre ich auf ewig dankbar. Ich muss noch viele weitere Abfragen optimieren - ich brauche nur ein Sprungbrett, um mir bei diesem ersten zu helfen.
Dies ist die Abfrage:
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
Was ich festgestellt habe, ist, dass die dritte Aussage (die als langsam bezeichnet wird) den Teil darstellt, der die meiste Zeit in Anspruch nimmt. Die beiden vorherigen Aussagen kehren fast sofort zurück.
Der Ausführungsplan steht unter diesem Link als XML zur Verfügung .
Klicken Sie besser mit der rechten Maustaste und speichern Sie sie und öffnen Sie sie in SQL Sentry Plan Explorer oder einer anderen Anzeigesoftware, anstatt sie in Ihrem Browser zu öffnen.
Wenn Sie weitere Informationen zu den Tabellen oder Daten von mir benötigen, zögern Sie bitte nicht, nachzufragen.
tempdb
. Das heißt, die Schätzungen für die Zeilen, die sich aus dem Join zwischen TableA
und ergeben, @MyTableVar
sind weit entfernt. Außerdem ist die Anzahl der Zeilen, die in die Sortierung einfließen, viel größer als angenommen, sodass sie auch überlaufen können.