use*_*692 3 t-sql sql-server asp.net performance reporting-services
通过在子查询中添加parens,结果立即在应用程序中返回.
当RS2005在vb.net/aspx web应用程序中调用时,运行速度很慢:
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 @StartDate and @EndDate
and c.schoolid = @SchoolID
and std.GradeID=@GradeLevel
GROUP BY
c.TeacherID, sb.behaviorID, b.BehaviorName, u.lname, u.FName,
std.GradeID, gl.GradeLevel
ORDER BY
u.LName, sb.behaviorID
Run Code Online (Sandbox Code Playgroud)
这快速运行:
select a.teacherid, a.teacher,a.bxcount, a.behaviorid,a.behaviorname,a.gradeid, a.gradelevel
from (
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 @StartDate and @EndDate
and c.schoolid = @SchoolID
and std.GradeID=@GradeLevel
group by c.TeacherID, sb.behaviorID, b.BehaviorName, u.lname, u.FName, std.GradeID, gl.GradeLevel
) a
order by a.teacher, a.behaviorid
Run Code Online (Sandbox Code Playgroud)
它们在SQL Server Management Studio的查询窗口中以相同的速度运行.为什么不同?谢谢.
您可能遇到过一个参数嗅探问题的查询,这与Sql Server如何尝试优化您的查询执行计划有关,但是在涉及Reporting Services时会完全混淆并使其运行速度极慢.
我有一个案例的报告有两个复杂的查询,每个约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;
Run Code Online (Sandbox Code Playgroud)