ที่สำนักงานของฉันเรามีข้อความค้นหาที่น่าเกลียด แต่ทำงานได้ค่อนข้างดีในการผลิตและในสภาพแวดล้อมการพัฒนา (20 วินาทีและ 4sec ตามลำดับ) อย่างไรก็ตามในสภาพแวดล้อมการทดสอบของเราใช้เวลามากกว่า 4 ชั่วโมง SQL2005 (+ แพตช์ล่าสุด) กำลังทำงานในการผลิตและการพัฒนา SQL2008R2 กำลังทำงานในการทดสอบ
ฉันดูที่ Query Plan และมันแสดงให้เห็นว่า SQL2008R2 กำลังใช้ TempDB โดย Table Spool (lazy spool) เพื่อจัดเก็บแถวที่ส่งคืนจากลิงก์เซิร์ฟเวอร์ ขั้นตอนต่อไปคือการแสดงลูปซ้อน (ซ้ายกึ่งต่อต้านเข้าร่วม) ขณะที่กินแบบสอบถามถึง 96.3% เส้นแบ่งระหว่างตัวดำเนินการทั้งสองอยู่ที่ 5,398MB!
แผนแบบสอบถามสำหรับ SQL 2005 ไม่แสดงการใช้ tempdb และไม่ใช้ Left Anti Semi Join
ด้านล่างนี้คือรหัสที่ถูกสุขอนามัยและการดำเนินการตามแผนในปี 2005 ด้านบนคือ 2008R2 ด้านล่าง
อะไรเป็นสาเหตุให้เกิดการเปลี่ยนแปลงอย่างรุนแรงและช้าลง? ฉันคาดหวังว่าจะเห็นแผนการดำเนินการที่แตกต่างกันดังนั้นมันจึงไม่รบกวนฉัน การชะลอตัวลงอย่างมากในเวลาสอบถามคือสิ่งที่ฉันมีปัญหา
ฉันต้องดูฮาร์ดแวร์พื้นฐานเนื่องจากรุ่น 2008R2 กำลังใช้ tempdb ฉันต้องดูที่วิธีเพิ่มประสิทธิภาพการใช้งานของมัน
มีวิธีที่ดีกว่าในการเขียนแบบสอบถามหรือไม่
ขอบคุณสำหรับความช่วยเหลือ
INSERT INTO Table1_GroupLock (iGroupID, dLockedDate)
SELECT
Table1.iGroupID,
GETDATE()
FROM Table1
WHERE
NOT EXISTS (
SELECT 1
FROM LinkedServer.Database.Table2 Alias2
WHERE
(
Alias2.FirstName + Alias2.LastName = dbo.fnRemoveNonLetter(Table1.FullName)
AND NOT dbo.fnRemoveNonLetter(Table1.FullName) IS NULL
AND NOT Alias2.FirstName IS NULL
AND NOT Alias2.LastName IS NULL
) OR (
Alias2.FamilyName = dbo.fnRemoveNonLetter(Table1.FamilyName)
AND Alias2.Child1Name = dbo.fnRemoveNonLetter(Table1.Child1Name)
AND NOT dbo.fnRemoveNonLetter(Table1.FamilyName) IS NULL
AND NOT dbo.fnRemoveNonLetter(Table1.Child1Name) IS NULL
AND NOT Alias2.Familyname IS NULL
AND NOT Alias2.Child1Name IS NULL
) OR (
Alias2.StepFamilyName = dbo.fnRemoveNonLetter(Table1.StepFamilyName)
AND Alias2.StepFamilyNameChild1 = dbo.fnRemoveNonLetter(Table1.StepFamilyNameChild2)
AND NOT Alias2.StepFamilyName IS NULL
AND NOT Alias2.StepFamilyNameChild1 IS NULL
AND NOT dbo.fnRemoveNonLetter(Table1.StepFamilyName) IS NULL
AND NOT dbo.fnRemoveNonLetter(Table1.StepFamilyNameChild2) IS NULL
)
) AND NOT EXISTS (
SELECT 1
FROM Table3
INNER JOIN Table4
ON Table4.FirstNameType = Table3.FirstNameType
INNER JOIN table5
ON table5.LastNameType = Table3.LastNameType
WHERE
Table3.iGroupID = Table1.iGroupID
AND Table3.bIsClosed = 0
AND Table4.sNameTypeConstant = 'new_lastname'
AND table5.sFirstNameConstant = 'new_firstname'
)
:: แก้ไข :: ดำเนินการแบบสอบถามจากอินสแตนซ์ SQL2005 ที่แตกต่างกันค่อนข้างมากแผนการดำเนินการเช่นเดียวกับ "ดีหนึ่ง" ยังไม่แน่ใจว่ารุ่น 2005 สองรุ่นทำงานอย่างไรกับเซิร์ฟเวอร์ที่เชื่อมโยง 2008R2 ได้ดีกว่าอินสแตนซ์ 2008R2 กับอินสแตนซ์ 2008R2
ในขณะที่ฉันไม่ปฏิเสธว่ารหัสสามารถใช้งานบางอย่างได้ แต่ถ้าเป็นปัญหาที่เกิดขึ้นกับรหัสฉันจะไม่เห็นแผน exec เดียวกันนี้ตลอดการทดลองทั้งหมดของฉันหรือไม่ ไม่ว่าจะเป็นเวอร์ชั่น SQL หรือไม่?
:: แก้ไข :: ฉันใช้ SP1 และ CU3 กับทั้งสองอินสแตนซ์ 2008R2 แล้วยังไม่มีลูกเต๋า ฉันได้ตั้งค่าการจัดวางเฉพาะในเซิร์ฟเวอร์ที่เชื่อมโยงโดยไม่มีลูกเต๋า ฉันได้ตั้งค่าการอนุญาตโดยเฉพาะสำหรับผู้ใช้ของฉันให้เป็นดูแลระบบทั้งสองกรณีไม่มีลูกเต๋า ฉันยังจำภายใน sql server 2008 internals และการแก้ไขปัญหาเราจะดูว่าฉันสามารถติดตามสิ่งนี้ได้อย่างไร
ขอบคุณทุกคนสำหรับความช่วยเหลือและเคล็ดลับ
:: แก้ไข :: ฉันทำการเปลี่ยนแปลงสิทธิ์ต่าง ๆ ไปยังเซิร์ฟเวอร์ที่เชื่อมโยงแล้ว ฉันใช้การเข้าสู่ระบบ SQL, การเข้าสู่ระบบโดเมน, ฉันมีผู้ใช้ที่ได้รับการเลียนแบบ, ฉันได้ใช้ตัวเลือก "ถูกสร้างขึ้นโดยใช้บริบทความปลอดภัยนี้" ฉันสร้างผู้ใช้ทั้งสองด้านของเซิร์ฟเวอร์ที่เชื่อมโยงซึ่งมีสิทธิ์ดูแลระบบบนเซิร์ฟเวอร์ ฉันไม่มีความคิด
ฉันยังอยากรู้ว่าทำไม SQL2005 จึงเรียกใช้งานแบบสอบถามจึงแตกต่างอย่างมากจาก SQL2008R2 ถ้ามันเป็นแบบสอบถามที่ไม่ดีฉันจะเห็นเวลารันไทม์ 4 + ชม. ทั้ง SQL2005 และ SQL2008R2