ฉันมีแบบสอบถาม SQL ที่ฉันใช้เวลาสองวันที่ผ่านมาพยายามเพิ่มประสิทธิภาพโดยใช้การทดลองและข้อผิดพลาดและแผนการดำเนินการ แต่ไม่มีประโยชน์ โปรดยกโทษให้ฉันที่ทำเช่นนี้ แต่ฉันจะโพสต์แผนการดำเนินการทั้งหมดที่นี่ ฉันได้ใช้ความพยายามในการสร้างชื่อตารางและคอลัมน์ในแบบสอบถามและแผนปฏิบัติการทั่วไปทั้งเพื่อความกระชับและเพื่อปกป้อง IP ของ บริษัท ของฉัน แผนปฏิบัติการสามารถเปิดได้กับSQL ยามแผน Explorer ที่
ฉันทำ T-SQL ในปริมาณที่พอใช้ แต่การใช้แผนการดำเนินการเพื่อเพิ่มประสิทธิภาพการสืบค้นของฉันเป็นพื้นที่ใหม่สำหรับฉันและฉันได้พยายามเข้าใจวิธีการทำ ดังนั้นหากใครสามารถช่วยฉันด้วยและอธิบายว่าแผนปฏิบัติการนี้สามารถถอดรหัสเพื่อค้นหาวิธีในการค้นหาเพื่อเพิ่มประสิทธิภาพได้ฉันจะขอบคุณตลอดไป ฉันมีคำถามเพิ่มเติมเพื่อเพิ่มประสิทธิภาพ - ฉันต้องการกระดานกระโดดน้ำเพื่อช่วยฉันในเรื่องนี้เป็นครั้งแรก
นี่คือแบบสอบถาม:
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
สิ่งที่ฉันได้พบคือข้อความที่สาม (แสดงความคิดเห็นว่าช้า) เป็นส่วนที่ใช้เวลามากที่สุด ทั้งสองงบก่อนกลับมาเกือบจะทันที
แผนการดำเนินการมีให้บริการเป็น XML ที่ลิงค์นี้
ดีกว่าคลิกขวาแล้วบันทึกจากนั้นเปิดใน SQL Sentry Plan Explorer หรือซอฟต์แวร์การดูอื่น ๆ แทนที่จะเปิดในเบราว์เซอร์ของคุณ
หากคุณต้องการข้อมูลเพิ่มเติมจากฉันเกี่ยวกับตารางหรือข้อมูลโปรดอย่าลังเลที่จะถาม
tempdb
มาได้ นั่นคือค่าประมาณของแถวที่เกิดจากการเข้าร่วมระหว่างTableA
และ@MyTableVar
ออกไป นอกจากนี้จำนวนแถวที่เข้าสู่การเรียงลำดับนั้นยิ่งใหญ่กว่าที่คาดไว้มาก