asp.net - 为什么在 Web 应用程序中由 Reporting Services 2005 调用时,第二个 T-SQL 查询的运行速度比第一个快得多

标签 asp.net sql-server performance tsql reporting-services

在子查询中添加括号后,结果立即在应用程序中返回。

在 vb.net/aspx Web 应用程序中由 RS2005 调用时,这运行缓慢:

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

这运行得很快:
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

它们在 SQL Server Management Studio 的查询窗口中以相同的速度运行。为什么会有差异?谢谢。

最佳答案

您可能遇到过 parameter sniffing 有问题的查询,这与 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;

关于asp.net - 为什么在 Web 应用程序中由 Reporting Services 2005 调用时,第二个 T-SQL 查询的运行速度比第一个快得多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16924144/

相关文章:

sql - azure sql数据库智能搜索算法需要建议

sql-server - EF Core (< 5.0) HasComputedColumnSql - 在插入/更新或 SQL Server/AzureSQL 上的每个查询时计算?

c# - 在 VisulaStudio 2017 上创建和编辑 ASP.net Web 表单项目

c# - 根据自定义条件防止个别 session 过期?

mysql - 这个 mysql 是否正确转换为 sql server?

linq-to-sql - 与旧版 SQL Insert 语句相比,LINQ Insertonsubmit 非常慢

mysql - 构建用户收藏夹表的正确方法是什么(性能)

java - 在同一实例上调用 equals() 是否比在更改实例上更快?

asp.net - 错误 : Must declare the scalar variable "@data"

c# - 有什么方法可以使电子邮件的主题加粗吗?