Möglicherweise sind Sie auf eine Abfrage gestoßen, die ein Problem mit dem Parameter-Sniffing hat, was damit zu tun hat, wie Sql Server versucht, Ihren Abfrageausführungsplan zu optimieren, aber in Fällen, in denen Reporting Services beteiligt ist, ihn völlig durcheinander bringt und unglaublich langsam läuft.
Ich hatte einen Fall mit einem Bericht, der zwei komplexe Abfragen mit jeweils etwa 150 Zeilen hatte, aber in meiner Entwicklungsumgebung in 7 Sekunden lief – der gesamte Bericht dauerte weniger als 10 Sekunden. Bei der Bereitstellung auf dem Produktions-SSRS-Server dauerte der Bericht jedoch mehr als 7 Minuten und es kam häufig zu einer Zeitüberschreitung, wodurch der Bericht nicht mehr ausgeführt werden konnte.
Die meisten Informationen zu diesem Problem beziehen sich auf gespeicherte Prozeduren. Verwerfen Sie dies nicht, weil Sie keine gespeicherten Prozeduren verwenden (wie ich es lange Zeit getan habe); Es ist auch für direkte SQL-Abfragen sehr relevant.
Der Unterschied, den Sie sehen, besteht also darin, dass SQL Server zwei sehr unterschiedliche Ausführungspläne erstellt, da die beiden Abfragen unterschiedlich strukturiert sind.
Glücklicherweise ist die Lösung sehr einfach:Setzen Sie die Parameter in interne Variablen und verwenden Sie diese stattdessen in Ihrer Abfrage. Ich habe dies mit meinem Bericht gemacht und der Produktionsbericht ging auf 10 Sekunden zurück, wie es die Entwicklungsversion in Visual Studio tat.
Um das Parameter-Sniffing für Ihre erste Abfrage zu umgehen, würden Sie es so aussehen lassen:
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;