2009-11-03 38 views
6

Tôi đang gặp sự cố khi hiểu hành vi của các kế hoạch truy vấn ước tính cho câu lệnh của tôi trong SQL Server khi thay đổi từ truy vấn được tham số hóa thành truy vấn không được tham số hóa.Sự khác biệt về kế hoạch truy vấn SQL Server

Tôi có truy vấn sau đây:

DECLARE @p0 UniqueIdentifier = '1fc66e37-6eaf-4032-b374-e7b60fbd25ea' 
SELECT [t5].[value2] AS [Date], [t5].[value] AS [New] 
FROM (
    SELECT COUNT(*) AS [value], [t4].[value] AS [value2] 
    FROM (
     SELECT CONVERT(DATE, [t3].[ServerTime]) AS [value] 
     FROM (
      SELECT [t0].[CookieID] 
      FROM [dbo].[Usage] AS [t0] 
      WHERE ([t0].[CookieID] IS NOT NULL) AND ([t0].[ProductID] = @p0) 
      GROUP BY [t0].[CookieID] 
      ) AS [t1] 
     OUTER APPLY (
      SELECT TOP (1) [t2].[ServerTime] 
      FROM [dbo].[Usage] AS [t2] 
      WHERE ((([t1].[CookieID] IS NULL) AND ([t2].[CookieID] IS NULL)) 
      OR (([t1].[CookieID] IS NOT NULL) AND ([t2].[CookieID] IS NOT NULL) 
      AND ([t1].[CookieID] = [t2].[CookieID]))) 
      AND ([t2].[CookieID] IS NOT NULL)   
      AND ([t2].[ProductID] = @p0) 
      ORDER BY [t2].[ServerTime] 
      ) AS [t3] 
     ) AS [t4] 
    GROUP BY [t4].[value] 
    ) AS [t5] 
ORDER BY [t5].[value2] 

Truy vấn này được tạo ra bởi một biểu thức Linq2SQL và chiết xuất từ ​​LINQPad. Điều này tạo ra một kế hoạch truy vấn tốt đẹp (theo như tôi có thể nói) và thực hiện trong khoảng 10 giây trên cơ sở dữ liệu. Tuy nhiên, nếu tôi thay thế hai lần sử dụng thông số bằng giá trị chính xác, thì thay thế hai phần '= @ p0' bằng '=' 1fc66e37-6eaf-4032-b374-e7b60fbd25ea '' Tôi nhận được một kế hoạch truy vấn ước tính khác và truy vấn bây giờ chạy lâu hơn nhiều (hơn 60 giây, không nhìn thấy nó thông qua).

Tại sao việc thực hiện thay thế dường như vô tội lại tạo ra kế hoạch và thực thi truy vấn hiệu quả hơn nhiều? Tôi đã xóa bộ nhớ cache thủ tục với 'DBCC FreeProcCache' để đảm bảo rằng tôi đã không lưu vào bộ nhớ cache một kế hoạch xấu, nhưng hành vi vẫn còn.

Vấn đề thực sự của tôi là tôi có thể sống với thời gian thực hiện 10 giây (ít nhất là trong một thời gian tốt) nhưng tôi không thể sống với thời gian thực hiện 60 giây. truy vấn của tôi sẽ (như gợi ý ở trên) bằng cách tạo ra bởi Linq2SQL vì vậy nó được thực hiện trên cơ sở dữ liệu như

exec sp_executesql N' 
     ... 
     WHERE ([t0].[CookieID] IS NOT NULL) AND ([t0].[ProductID] = @p0) 
     ... 
     AND ([t2].[ProductID] = @p0) 
     ... 
     ',N'@p0 uniqueidentifier',@p0='1FC66E37-6EAF-4032-B374-E7B60FBD25EA' 

trong đó sản xuất đồng thời thực hiện kém (mà tôi nghĩ là gấp đôi kỳ lạ vì đây dường như được sử dụng các truy vấn tham số.

tôi không tìm kiếm lời khuyên mà chỉ để tạo ra hoặc những thứ tương tự, tôi chỉ cố gắng tìm hiểu tại sao kế hoạch truy vấn và thực hiện rất khác nhau trên ba câu hỏi dường như tương tự

EDIT:. Tôi đã tải lên kế hoạch thực hiện cho không tham số hóa và truy vấn tham số cũng như một kế hoạch thực hiện cho một truy vấn tham số (theo đề nghị của Heinz) với một khác nhau GUID here

Hy vọng nó sẽ giúp bạn giúp tôi :)

+1

Bạn có thể đăng các gói truy vấn bạn nhận được không? Chỉ cần chạy 'SET SHOWPLAN_TEXT ON GO SELECT…' – Quassnoi

+0

Xong ... Đã thêm liên kết vào kế hoạch thực hiện ... –

Trả lời

2

Tôi không tìm kiếm tư vấn về chỉ mục để tạo hoặc tương tự, tôi chỉ đang cố gắng hiểu tại sao kế hoạch truy vấn và thực thi lại khác nhau với ba truy vấn dường như tương tự.

Bạn dường như có hai chỉ số:

IX_NonCluster_Config (ProductID, ServerTime) 
IX_NonCluster_ProductID_CookieID_With_ServerTime (ProductID, CookieID) INCLUDE (ServerTime) 

Chỉ số đầu tiên không bao gồm CookieID nhưng lệnh trên ServerTime và do đó là hiệu quả hơn cho các ít chọn lọc ProductID 's (tức là những người bạn có nhiều)

Chỉ mục thứ hai bao gồm tất cả các cột nhưng không được đặt hàng và do đó hiệu quả hơn đối với thêm chọn lọc ProductID (những thứ bạn có ít).

Trung bình, bạn cardinality là để SQL Server hy vọng phương pháp thứ hai có hiệu quả, đó là phương pháp nào sử dụng khi bạn sử dụng truy vấn được yêu cầu hoặc cung cấp rõ ràng lựa chọn GUID.

Tuy nhiên, GUID gốc của bạn được coi là ít chọn lọc hơn, đó là lý do tại sao phương pháp đầu tiên được sử dụng.

Thật không may, phương pháp đầu tiên yêu cầu lọc bổ sung trên CookieID đó là lý do tại sao nó kém hiệu quả hơn trong thực tế.

+0

Ahh ... có lẽ điều này cũng giải thích lý do tại sao tôi thực hiện "nhanh" nếu tôi xóa các phần dư thừa của mệnh đề where (các phần HOẶC kiểm tra IS NULL là thừa) không có bộ lọc bổ sung nào được yêu cầu trên CookieID. Các truy vấn được tạo ra thông qua Linq2SQL để tôi không thể thực sự sửa đổi nhưng tôi sẽ kiểm tra để xem nếu tôi có thể làm cho cột Không-Null mà dường như để loại bỏ các điều khoản additonal và tạo ra các truy vấn nhanh. –

1

Tôi đoán là khi bạn đi theo con đường phi paramaterized , guid của bạn phải được chuyển đổi từ một varchar thành một UniqueIdentifier mà có thể gây ra một chỉ mục không được sử dụng, trong khi nó sẽ được sử dụng tham gia tuyến đường paramatarized.

Tôi đã thấy điều này xảy ra với việc sử dụng các truy vấn có một ngày nhỏ trong mệnh đề where đối với cột sử dụng datetime.

3

Nếu bạn cung cấp giá trị rõ ràng, SQL Server có thể sử dụng số liệu thống kê của trường này để đưa ra quyết định "kế hoạch truy vấn" tốt hơn. Thật không may (như tôi đã có kinh nghiệm bản thân mình gần đây), nếu thông tin chứa trong các số liệu thống kê là gây hiểu lầm, đôi khi SQL Server chỉ làm cho sự lựa chọn sai.

Nếu bạn muốn tìm hiểu sâu hơn về vấn đề này, tôi khuyên bạn nên kiểm tra xem điều gì xảy ra nếu bạn sử dụng GUID khác: Nếu nó sử dụng một kế hoạch truy vấn khác cho GUID cụ thể khác nhau, đó là dấu hiệu cho thấy dữ liệu thống kê được sử dụng. Trong trường hợp đó, bạn có thể muốn xem sp_updatestats và các lệnh liên quan.

EDIT: Hãy xem DBCC SHOW_STATISTICS: GUID "chậm" và "nhanh" có thể nằm trong các nhóm khác nhau trong biểu đồ. Tôi đã had a similar problem, mà tôi đã giải quyết bằng cách thêm một INDEX table hint vào SQL, hướng dẫn "SQL Server" hướng tới việc tìm kiếm kế hoạch truy vấn "đúng".Về cơ bản, tôi đã xem xét các chỉ số nào được sử dụng trong một truy vấn "nhanh" và các chỉ mục được mã hóa cứng vào trong SQL. Đây là một giải pháp tối ưu hoặc thanh lịch, nhưng tôi chưa tìm được giải pháp nào tốt hơn ...

+0

Chỉ cần thử chạy chậm, không tham số hóa với GUID khác và nó tạo ra một kế hoạch truy vấn tốt và được thực hiện như mong đợi. Có lẽ bạn có thể xây dựng trên những gì tôi cần phải tìm kiếm liên quan đến các số liệu thống kê? Đó có phải là một chỉ mục cụ thể cần phải xây dựng lại hoặc tương tự không? –

+0

Tôi đã chỉnh sửa bài đăng của mình để thêm một số chi tiết khác. – Heinzi

+0

Phải thừa nhận rằng cái nhìn đầu tiên của tôi về DBBC SHOW_STATISTICS nhưng tôi dường như giải mã rằng GUID nằm trong các thùng riêng biệt ("chậm" với RANGE_ROWS bằng 316 và "nhanh" với RANGE_ROWS bằng 0 (?)). Thật không may tôi đang sử dụng Linq2SQL vì vậy tôi không có đường dẫn thực sự để thiết lập gợi ý truy vấn. Tôi có thể tính toán lại số liệu thống kê bằng cách nào đó không? –

0

Thật khó để nói mà không xem xét kế hoạch thực hiện, tuy nhiên nếu tôi dự đoán Tôi muốn nói rằng đó là một combinaton của sniffing tham số và số liệu thống kê nghèo - Trong trường hợp bạn mã cứng GUID vào truy vấn, trình tối ưu hóa truy vấn cố gắng tối ưu hóa truy vấn cho giá trị đó của tham số. Tôi tin rằng điều tương tự cũng xảy ra với truy vấn tham số/chuẩn bị (được gọi là tham số sniffing - kế hoạch thực hiện được tối ưu hóa cho các tham số được sử dụng lần đầu tiên mà câu lệnh đã chuẩn bị được thực hiện), tuy nhiên điều này chắc chắn không xảy ra khi bạn khai báo tham số và sử dụng nó trong truy vấn.

Như tôi đã nói, máy chủ SQL cố gắng tối ưu hóa kế hoạch thực hiện cho giá trị đó và vì vậy thường bạn sẽ thấy kết quả tốt hơn. Có vẻ như ở đây thông tin đó dựa trên các quyết định của nó là không chính xác/gây nhầm lẫn và bạn tốt hơn (vì một lý do nào đó) khi nó tối ưu hóa truy vấn cho một giá trị thông số chung.

Tuy nhiên, điều này hầu như không thể thực hiện được - nếu bạn có thể tải lên kế hoạch thực hiện ở đâu đó thì tôi chắc chắn ai đó có thể giúp bạn với lý do thực sự.

+0

Tải lên kế hoạch thực hiện, xem bài chỉnh sửa của tôi –

Các vấn đề liên quan