sql >> Databáze >  >> RDS >> Sqlserver

Proč druhý dotaz T-SQL běží mnohem rychleji než první, když je volán službou Reporting Services 2005 ve webové aplikaci

Možná jste narazili na dotaz, který má problém s čicháním parametrů, což souvisí s tím, jak se Sql Server snaží optimalizovat váš plán provádění dotazů, ale v případech, kdy je zapojena služba Reporting Services, to úplně zkazí a zpomalí běh.

Měl jsem případ se sestavou, která měla dva složité dotazy, každý o délce přibližně 150 řádků, ale která se v mém vývojovém prostředí spustila za 7 sekund – celá sestava trvala méně než 10 sekund. Při nasazení na produkční server SSRS však sestava trvala déle než 7 minut a často vypršel časový limit, takže sestavu nebylo možné spustit.

Většina informací o tomto problému o něm hovoří ve vztahu k uloženým procedurám. Nezavrhujte to, protože nepoužíváte uložené procedury (jako já po dlouhou dobu); je také velmi relevantní pro přímé dotazy SQL.

Rozdíl, který vidíte, je ten, že SQL Server vytváří dva velmi odlišné plány provádění, protože tyto dva dotazy jsou strukturovány odlišně.

Naštěstí je řešení velmi jednoduché:vložte parametry do interních proměnných a místo toho je použijte ve svém dotazu. Udělal jsem to se svou zprávou a zpráva o produkci se vrátila na 10 sekund jako vývojová verze ve Visual Studiu.

Chcete-li obejít sniffování parametrů pro váš první dotaz, vypadalo by to takto:

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;



  1. Udělte vše na konkrétním schématu v db skupinové roli v PostgreSQL

  2. 5 úloh, které vyžadují Microsoft Access

  3. jak změnit barvu pruhu v MPandroidCharts na základě nějaké individuální hodnoty uložené v sqlite?

  4. Vrátit všechny skupiny souborů pro aktuální databázi na serveru SQL Server