हो सकता है कि आपने एक ऐसी क्वेरी देखी हो जिसमें पैरामीटर सूँघने की समस्या है, जिसका संबंध यह है कि Sql सर्वर आपकी क्वेरी निष्पादन योजना को कैसे अनुकूलित करने का प्रयास करता है, लेकिन ऐसे मामलों में जब रिपोर्टिंग सेवाएँ शामिल होती हैं तो यह पूरी तरह से गड़बड़ कर देती है और इसे अविश्वसनीय रूप से धीमी गति से चलती है।
मेरे पास एक रिपोर्ट का मामला था जिसमें लगभग 150 पंक्तियों के दो जटिल प्रश्न थे, लेकिन जो मेरे विकास के माहौल में 7 सेकंड में चले - पूरी रिपोर्ट में 10 सेकंड से भी कम समय लगा। हालांकि, जब उत्पादन एसएसआरएस सर्वर पर तैनात किया गया तो रिपोर्ट में 7 मिनट से अधिक समय लगा और अक्सर रिपोर्ट को अप्राप्य बना दिया गया।
इस मुद्दे के बारे में अधिकांश जानकारी संग्रहीत प्रक्रियाओं के संबंध में इसके बारे में बात करती है। इसे खारिज न करें क्योंकि आप संग्रहित प्रक्रियाओं का उपयोग नहीं कर रहे हैं (जैसे मैंने लंबे समय तक किया था); यह सीधे एसक्यूएल प्रश्नों के लिए भी बहुत प्रासंगिक है।
तो आप जो अंतर देख रहे हैं वह यह है कि Sql सर्वर दो अलग-अलग निष्पादन योजनाएँ बना रहा है क्योंकि दो क्वेरीज़ अलग-अलग संरचित हैं।
सौभाग्य से, समाधान बहुत सरल है:मापदंडों को आंतरिक चर में रखें और इसके बजाय अपनी क्वेरी में इनका उपयोग करें। मैंने इसे अपनी रिपोर्ट के साथ किया और उत्पादन रिपोर्ट 10 सेकंड में वापस चली गई जैसे कि विजुअल स्टूडियो में विकास संस्करण किया गया था।
अपनी पहली क्वेरी के लिए पैरामीटर सूँघने को बायपास करने के लिए आप इसे इस तरह दिखाएंगे:
BEGIN
-- Use internal variables to solve parameter sniffing issues
DECLARE @StartDateInternal AS DATETIME;
DECLARE @EndDateInternal AS DATETIME;
DECLARE @SchoolIDInternal AS INT;
DECLARE @GradeLevelInternal AS INT;
-- Copy the parameters into the internal variables
SET @StartDateInternal = @StartDate;
SET @EndDateInternal = @EndDate;
SET @SchoolIDInternal = @SchoolID;
SET @GradeLevelInternal = @GradeLevel;
-- Now use the internal variables in your query rather than the parameters
SELECT
c.TeacherID, u.FName + ' ' + u.lname as Teacher, count(sb.behaviorID) as BxCount,
sb.behaviorID, b.BehaviorName, std.GradeID, gl.GradeLevel
FROM
StudentBehaviors sb
join
Classes c on sb.classid = c.classid
join
StudentDetails std on sb.studentID = std.StudentID and std.RecordIsActive=1
join
users u on c.TeacherID = u.UserID
join
Behaviors b on sb.behaviorID = b.BehaviorID
join
GradeLevels gl on std.GradeID = gl.GradeLevelID
WHERE
sb.classdate between @StartDateInternal and @EndDateInternal
and c.schoolid = @SchoolIDInternal
and std.GradeID = @GradeLevelInternal
GROUP BY
c.TeacherID, sb.behaviorID, b.BehaviorName, u.lname, u.FName,
std.GradeID, gl.GradeLevel
ORDER BY
u.LName, sb.behaviorID;
END;