Ok, vì vậy tôi có một truy vấn thủ tục không được lưu trữ mà chúng tôi đang sử dụng trong báo cáo SSRS. Truy vấn này đã được hellishly chậm (Tôi đã có gốc phiên bản của truy vấn này chạy trong hai giờ qua, vẫn không được thực hiện), trong một nỗ lực để cải thiện nó tôi viết lại nó từ đầu, và tôi đã đưa ra như sau:
Bây giờ đây là phần vấn đề từ nhàm chán:
Chúng tôi muốn kéo một danh sách các TOP 5
khách hàng mỗi đại diện bán hàng, nhưng loại trừ các TOP 10
tổng khách hàng từ danh sách đó. (Vì vậy, nếu John Doe có khách hàng A, B, C, D và E và khách hàng C là một trong số 10 khách hàng hàng đầu, thì chỉ kéo A, B, D và E.)
Để làm điều này, truy vấn đầu tiên đã sử dụng a IN (... NOT IN ( ) )
, vì vậy tôi nghĩ rằng việc lồng vào IN
là vấn đề, để viết lại tôi đã làm một OUTER APPLY
việc thực sự phá vỡ mọi thứ.
Dù sao, tôi đã sửa tất cả những thứ đó và tôi chạy truy vấn, và nó vẫn mất 10 - 15 giây mà tôi cho là tham số đánh hơi. Để điều tra, tôi đã chạy truy vấn trong SSMS, được thêm vào OPTION (RECOMPILE)
(để xem kế hoạch truy vấn nào sẽ tạo ra) và nhận được thông tin sau:
Nó có thể được xem ở đây trên 'Dán kế hoạch' của Brent Ozar . Truy vấn đã tạo ra điều này là:
DECLARE @Top10Temp TABLE (Id INT)
INSERT INTO @Top10Temp
SELECT TOP 10 Id
FROM Object1
WHERE Column2 = @ReportId
AND Column3 = 0
GROUP BY Id
ORDER BY SUM(Column4 + Column5) DESC
SELECT Object2.*
FROM Object1 AS Object2
OUTER APPLY (
SELECT TOP 5
Object3.Id,
SUM(Object3.Column4 + Object3.Column5) AS Column6
FROM Object1 AS Object3
WHERE Object3.Column3 = 0
AND Object3.Column7 = Object2.Column7
AND Object3.Column2 = @ReportId
GROUP BY
Object3.Id
ORDER BY
SUM(Object3.Column4 + Object3.Column5) DESC
) AS Object4
WHERE Object2.Column2 = @ReportId
AND Object2.Column3 = 0
AND Object2.Id = Object4.Id
AND Object2.Id NOT IN (SELECT Id FROM @Top10Temp)
ORDER BY Object2.Column7
OPTION (RECOMPILE)
Bây giờ cùng một truy vấn nhưng với OPTION (OPTIMIZE FOR UNKNOWN)
kế hoạch đã tạo:
Mà cũng có thể được xem tại 'Dán kế hoạch' . Kế hoạch này được thực hiện trong chưa đầy 1 giây.
Nếu tôi thêm OPTION (OPTIMIZE FOR (@ReportId = #))
, mà #
là tương tự như các @ReportId
biến, tôi nhận được kế hoạch truy vấn giống như thứ hai.
Tôi đã làm gì sai sao? Tôi gặp khó khăn trong việc hiểu những gì đã xảy ra, vì vậy bất kỳ thông tin nào cũng được đánh giá cao. (Tôi cũng thực sự không thích cố gắng tác động đến trình tối ưu hóa thông qua các gợi ý, nhưng nếu cần tôi sẽ giữ nó.)