Може да сте попаднали на заявка, която има проблем с подслушването на параметри, което е свързано с начина, по който Sql Server се опитва да оптимизира плана за изпълнение на заявката ви, но в случаите, когато услугите за докладване са включени, напълно го обърква и го кара да работи невероятно бавно.
Имах случай с отчет, който имаше две сложни заявки от около 150 реда всяка, но който се изпълняваше за 7 секунди в моята среда за разработка - целият отчет отне по-малко от 10 секунди. Въпреки това, когато се разположи на производствения SSRS сървър, отчетът отне повече от 7 минути и често изтича, което прави отчета неизпълним.
Повечето информация за този проблем говори за него във връзка със съхранените процедури. Не отхвърляйте това, защото не използвате съхранени процедури (както правех от дълго време); той е много уместен и за прави Sql заявки.
Така че разликата, която виждате, е, че Sql Server създава два много различни плана за изпълнение, тъй като двете заявки са структурирани по различен начин.
За щастие решението е много просто:поставете параметрите във вътрешни променливи и вместо това ги използвайте във вашата заявка. Направих това с моя отчет и производственият отчет се върна до 10 секунди, както направи версията за разработка във Visual Studio.
За да заобиколите подслушването на параметри за първата си заявка, ще я накарате да изглежда така:
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;