Truy vấn chạy khác nhau trên SQL 2005 so với SQL 2008R2


9

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'
 )

SQL-2005


SQL2008R2

:: 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.

Câu trả lời:


5

Tôi muốn bạn làm lại truy vấn.

Bạn có các vấn đề về khả năng mở rộng và thậm chí đang sử dụng các lệnh gọi hàm vô hướng trong đó, điều này cũng sẽ làm tổn hại đến truy vấn. Bạn có thể muốn tạo một cột được tính toán FullName trên Bảng2 và đặt một chỉ mục trên đó, đảm bảo chỉ mục của bạn INCLUDEs FirstName và LastName. Bạn cũng nên thêm các chỉ mục giúp người khác

Ngoài ra, tạo một hàm có giá trị bảng nội tuyến để thực hiện chức năng "RemoveNonLetter" của bạn và làm lại truy vấn của bạn để sử dụng chức năng đó, có thể sử dụng ỨNG DỤNG như tôi đã làm ở đây.

Và chắc chắn kiểm tra lỗi mà câu trả lời của Paul đề cập đến.

INSERT INTO Table1_GroupLock (iGroupID, dLockedDate)
SELECT 
 Table1.iGroupID,
 GETDATE()
FROM Table1
OUTER APPLY (SELECT NonLettersRemoved FROM dbo.ifnRemoveNonLetter(Table1.FullName)) AS fn (FullName)
OUTER APPLY (SELECT NonLettersRemoved FROM dbo.ifnRemoveNonLetter(Table1.FamilyName)) AS famn (FamilyName)
OUTER APPLY (SELECT NonLettersRemoved FROM dbo.ifnRemoveNonLetter(Table1.Child1Name)) AS c1n (Child1Name)
OUTER APPLY (SELECT NonLettersRemoved FROM dbo.ifnRemoveNonLetter(Table1.StepFamilyName)) AS sfn (StepFamilyName)
OUTER APPLY (SELECT NonLettersRemoved FROM dbo.ifnRemoveNonLetter(Table1.StepFamilyNameChild2)) AS sfnc2 (StepFamilyNameChild2)
WHERE 
 NOT EXISTS (
  SELECT 1
  FROM LinkedServer.Database.Table2 Alias2
  WHERE Alias2.FullName = fn.FullName
  UNION ALL
  SELECT 1
  FROM LinkedServer.Database.Table2 Alias2
  WHERE Alias2.FamilyName = famn.FamilyName AND Alias2.Child1Name = c1n.Child1Name
  UNION ALL
  SELECT 1
  FROM LinkedServer.Database.Table2 Alias2
  WHERE Alias2.StepFamilyName = sfn.StepFamilyName AND Alias2.StepFamilyNameChild1 = sfnc2.StepFamilyNameChild2
 ) 
 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'
 )
;

6

Thêm vào các câu trả lời trước đó, lý do cho hồi quy kế hoạch có thể là do lỗi ước tính cardinality đã biết khi kế hoạch bao gồm Anti Semi Join. Xem KB 2222998

Giả sử kế hoạch năm 2005 tạo ra hiệu suất chấp nhận được, bạn có thể thấy việc đưa máy chủ lên phiên bản bao gồm sửa lỗi đó (và cho phép TF4199 kích hoạt nó) sẽ đưa bạn trở lại kế hoạch 'tốt'.

Điều đó nói rằng, có nhiều cơ hội khác để cải thiện truy vấn đó, vì vậy đây có thể là thời điểm tốt để tập trung vào việc đó thay vào đó.


5

Tôi đề nghị rằng dữ liệu từ xa được lưu trữ cục bộ vì một trong những

  1. Cài đặt máy chủ được liên kết (như đối chiếu) không giống nhau
  2. Đối chiếu cục bộ không giống như điều khiển từ xa, mặc dù cài đặt máy chủ được liên kết
  3. Truy vấn không thể chạy chính xác từ xa vì quyền

Đối với điểm 1, xem sp_serveroption
Và cho điểm 2, nhưng cũng kiểm tra các đối chiếu máy chủ / db.

Đối với điểm 3, hãy xem những điều này từ Linchi Shea:

Bạn đang yêu cầu SQL Server xử lý tất cả dữ liệu cục bộ, theo câu trả lời của tôi ở đây: Ý nghĩa về hiệu suất của việc sử dụng OPENQUERY trong chế độ xem

Biên tập

Ở cái nhìn thứ hai, tôi thấy 2 cuộc gọi từ xa trong kế hoạch "tốt" chứ không phải một. Điều này xác nhận những gì tôi nói ở đây


Xin lỗi vì sự chậm trễ lâu dài. 1: Tôi đã kiểm tra các cài đặt máy chủ được liên kết, chúng giống nhau 2: Tôi cũng đã kiểm tra và đặt ngầm định đối chiếu các thuộc tính máy chủ được liên kết với máy chủ từ xa. 3: Bối cảnh bảo mật tôi vẫn đang thực hiện thử nghiệm A / B. Tôi vẫn còn lúng túng về logic đằng sau các kế hoạch thực hiện khác nhau mạnh mẽ. Từ máy chủ R2 đến máy chủ R2, nó chỉ chạy lệnh chọn (kéo theo hơn 150K hàng), sau đó thực hiện các phép nối. Trong trường hợp từ năm 2005 đến R2, nó đang thực hiện các lựa chọn và tham gia trên máy chủ từ xa. Bối cảnh bảo mật cho cả hai kịch bản là như nhau.
RateControl

3

+1 trên Thử Viết lại nhận xét truy vấn của bạn từ datagod.

Tôi cũng tự hỏi nếu bạn đang va vào một vấn đề quyền ở phía máy chủ được liên kết dẫn đến sự chậm lại này. Tôi đã viết blog về máy chủ được liên kết này chậm lại một lúc trước. Có thể đáng để xác minh các perm (nó có phải là máy chủ được liên kết SQL không? Hoặc nó có phải là một DBMS khác không? Nếu sau này, bạn sẽ không nhận được số liệu thống kê tuyệt vời nào)

Bạn có SQL Server 2005 trên môi trường thử nghiệm để thử truy vấn này và loại trừ môi trường không?

Bạn đã xây dựng lại số liệu thống kê kể từ khi nâng cấp?


3

Có quá nhiều vấn đề với sự so sánh này ... Tôi chỉ không biết bắt đầu từ đâu.

  1. Lấy thông số kỹ thuật chính xác cho máy sản xuất và thử nghiệm của bạn.

  2. Xác định các liên kết mạng giữa các sever được liên kết khác nhau trong cả hai môi trường. Họ có cùng tốc độ không? Là các máy chủ được đặt cạnh nhau trong cả hai môi trường?

  3. Có cách nào để bạn có thể viết lại truy vấn KHÔNG sử dụng các máy chủ được liên kết không? Tham gia các bảng trên các máy chủ khiến bạn dễ bị thay đổi cấu trúc liên kết và chậm kinh khủng trong hầu hết các trường hợp.

  4. Việc sử dụng KHÔNG và OR thường dẫn đến quét toàn bộ bảng. Hãy thử viết lại truy vấn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.