Du kanske har stött på en fråga som har ett problem med parametersniffning, vilket har att göra med hur SQL Server försöker optimera din frågeexekveringsplan, men i de fall då Reporting Services är inblandad förstör det fullständigt och gör att det körs otroligt långsamt.
Jag hade ett fall med en rapport som hade två komplexa frågor på cirka 150 rader vardera men som kördes på 7 sekunder i min utvecklingsmiljö - hela rapporten tog mindre än 10 sekunder. Men när den distribuerades till produktions-SSRS-servern tog rapporten mer än 7 minuter och tog ofta timeout, vilket gjorde att rapporten inte kunde köras.
Den mesta informationen om det här problemet handlar om det i relation till lagrade procedurer. Avvisa inte detta eftersom du inte använder lagrade procedurer (som jag gjorde under en lång tid); det är mycket relevant för raka SQL-frågor också.
Så skillnaden du ser är att SQL Server skapar två mycket olika exekveringsplaner eftersom de två frågorna är strukturerade på olika sätt.
Lyckligtvis är lösningen väldigt enkel:lägg in parametrarna i interna variabler och använd dessa i din fråga istället. Jag gjorde detta med min rapport och produktionsrapporten gick tillbaka till 10 sekunder som utvecklingsversionen gjorde i Visual Studio.
För att kringgå parametersniffning för din första fråga skulle du få det att se ut så här:
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;