Deneme-yanılma ve yürütme planı, ancak boşuna kullanarak optimize etmeye çalışırken son iki gün geçirdim bir SQL sorgusu var. Lütfen bunu yaptığım için beni affet ama tüm infaz planını buraya göndereceğim. Sorgu ve yürütme planındaki tablo ve sütun adlarının hem kısalık hem de şirketimin IP'sini korumak için genel bir çaba gösterdim. Yürütme planı SQL Sentry Plan Explorer ile açılabilir .
T-SQL adil bir miktar yaptım, ama benim sorgu optimize etmek için yürütme planları kullanarak benim için yeni bir alandır ve gerçekten bunu nasıl anlamaya çalıştım. Yani, kimse bana bu konuda yardımcı olabilir ve bu yürütme planı sorgu optimize etmek için yollar bulmak için nasıl deşifre edilebilir açıklayabilir, ben sonsuza dek minettar olacaktır. Optimize etmek için daha fazla sorgum var - sadece bu konuda bana yardımcı olacak bir sıçrama tahtası gerekiyor.
Bu sorgu:
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
Ne buldum üçüncü ifade (yavaş olarak yorumladı) en fazla zaman alan parçasıdır. İki ifade önce neredeyse anında geri dönüyor.
Yürütme planı bu bağlantıda XML olarak kullanılabilir .
Sağ tıklayıp kaydetmek ve tarayıcınızda açmak yerine SQL Sentry Plan Explorer'da veya başka bir görüntüleme yazılımında açmak daha iyidir.
Tablolar veya veriler hakkında benden daha fazla bilgiye ihtiyacınız varsa, lütfen sormaktan çekinmeyin.
tempdb
. arasında birleştirme kaynaklanan satırlar için tahminler yani TableA
ve @MyTableVar
kapalı yol vardır. Ayrıca, sıralara giren satırların sayısı tahmin edilenden çok daha fazla olduğundan dökülmeleri de iyi olabilir.