Tôi có một truy vấn SQL mà tôi đã dành hai ngày qua để cố gắng tối ưu hóa bằng cách sử dụng thử và lỗi và kế hoạch thực hiện, nhưng không có kết quả. Xin vui lòng tha thứ cho tôi vì đã làm điều này nhưng tôi sẽ đăng toàn bộ kế hoạch thực hiện ở đây. Tôi đã nỗ lực để đặt tên bảng và cột trong kế hoạch truy vấn và thực thi chung chung cho ngắn gọn và để bảo vệ IP của công ty tôi. Kế hoạch thực hiện có thể được mở bằng SQL Sentry Plan Explorer .
Tôi đã thực hiện một số lượng T-SQL khá lớn, nhưng sử dụng các kế hoạch thực hiện để tối ưu hóa truy vấn của tôi là một lĩnh vực mới đối với tôi và tôi đã thực sự cố gắng hiểu cách thực hiện. Vì vậy, nếu bất cứ ai có thể giúp tôi với điều này và giải thích cách giải mã kế hoạch thực hiện này để tìm cách trong truy vấn để tối ưu hóa nó, tôi sẽ biết ơn mãi mãi. Tôi có nhiều truy vấn khác để tối ưu hóa - tôi chỉ cần một bàn đạp để giúp tôi với câu hỏi đầu tiên này.
Đây là truy vấn:
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
Những gì tôi đã tìm thấy là tuyên bố thứ ba (nhận xét là chậm) là phần mất nhiều thời gian nhất. Hai tuyên bố trước khi trở lại gần như ngay lập tức.
Kế hoạch thực hiện có sẵn dưới dạng XML tại liên kết này .
Tốt hơn là nhấp chuột phải và lưu và sau đó mở trong SQL Sentry Plan Explorer hoặc một số phần mềm xem khác thay vì mở trong trình duyệt của bạn.
Nếu bạn cần thêm thông tin từ tôi về các bảng hoặc dữ liệu, xin đừng ngần ngại hỏi.
tempdb
. tức là các ước tính cho các hàng kết quả từ sự nối giữa TableA
và @MyTableVar
đang tắt. Ngoài ra, số lượng các hàng đi vào các loại lớn hơn nhiều so với ước tính vì vậy chúng cũng có thể bị đổ.