Tại văn phòng của tôi, chúng tôi có một truy vấn khá xấu, nhưng chạy khá tốt trong sản xuất và trong môi trường phát triển (lần lượt là 20 giây và 4 giây). Tuy nhiên, trong môi trường thử nghiệm của chúng tôi, phải mất hơn 4 giờ. SQL2005 (+ bản vá mới nhất) đang chạy trong sản xuất và phát triển. SQL2008R2 đang chạy thử nghiệm.
Tôi đã xem qua Kế hoạch truy vấn và nó cho thấy SQL2008R2 đang sử dụng TempDB, bằng cách sử dụng Bộ đệm bảng (bộ đệm lười biếng) để lưu trữ các hàng được trả về từ máy chủ được liên kết. Bước tiếp theo là hiển thị các vòng lặp Nested (trái chống bán tham gia) khi ăn tới 96,3% truy vấn. Dòng giữa hai nhà khai thác là 5.398 MB!
Kế hoạch truy vấn cho SQL 2005 cho thấy không sử dụng tempdb và không sử dụng Left Anti Semi Join.
Dưới đây là mã được khử trùng và kế hoạch thực hiện kế hoạch năm 2005 ở trên cùng, 2008R2 ở phía dưới.
Điều gì gây ra sự quyết liệt chậm lại và thay đổi? Tôi đã mong đợi để xem một kế hoạch thực hiện khác, vì vậy điều đó không làm phiền tôi. Sự chậm lại đáng kể trong thời gian truy vấn là những gì làm phiền tôi.
Tôi có phải xem xét phần cứng cơ bản không, vì phiên bản 2008R2 đang sử dụng tempdb nên tôi phải xem cách tối ưu hóa việc sử dụng đó?
Có cách nào tốt hơn để viết truy vấn không?
Cảm ơn đã giúp đỡ.
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'
)
:: EDIT :: Đã thực hiện truy vấn từ một phiên bản SQL2005 khác, khá giống với kế hoạch thực hiện giống như "kế hoạch tốt". Vẫn không chắc chắn làm thế nào hai phiên bản 2005 đang chạy tốt hơn với máy chủ được liên kết 2008R2, so với phiên bản 2008R2 so với phiên bản 2008R2.
Mặc dù tôi không phủ nhận rằng mã có thể sử dụng một số công việc, nhưng nếu đó là mã là vấn đề, tôi sẽ không thấy các kế hoạch thực thi tương tự trong tất cả các thử nghiệm của mình chứ? Bất kể phiên bản SQL là gì?
:: EDIT :: Tôi đã áp dụng SP1 và CU3 cho cả hai phiên bản 2008R2, vẫn không có xúc xắc. Tôi đặc biệt thiết lập sắp xếp thứ tự trong máy chủ được liên kết, không có xúc xắc. Tôi đặc biệt đặt quyền của acct người dùng của mình là sysadmin trên cả hai trường hợp, không có xúc xắc. Tôi cũng đã nhớ nội bộ máy chủ sql 2008 và xử lý sự cố, chúng tôi sẽ xem liệu tôi có thể theo dõi điều này không.
Cảm ơn mọi người đã giúp đỡ và những lời khuyên.
:: EDIT :: Tôi đã thực hiện nhiều thay đổi cấp phép cho máy chủ được liên kết. Tôi đã sử dụng thông tin đăng nhập SQL, đăng nhập tên miền, tôi đã mạo danh người dùng, tôi đã sử dụng tùy chọn "được thực hiện bằng bối cảnh bảo mật này". Tôi đã tạo người dùng ở cả hai phía của máy chủ được liên kết có quyền sysadmin trên máy chủ. Tôi không có ý kiến.
Tôi vẫn muốn biết tại sao SQL2005 lại thực hiện truy vấn khác biệt đáng kể so với SQL2008R2. Nếu đó là truy vấn xấu, tôi sẽ thấy thời gian chạy 4 + giờ trên cả SQL2005 và SQL2008R2.