sql >> Database teknologi >  >> RDS >> Sqlserver

Hvorfor kører den 2. T-SQL-forespørgsel meget hurtigere end den første, når den kaldes af Reporting Services 2005 i en web-app

Du er muligvis stødt på en forespørgsel, der har et problem med parametersniffing, hvilket har at gøre med, hvordan SQL Server forsøger at optimere din plan for udførelse af forespørgsler, men i tilfælde, hvor Reporting Services er involveret, roder det fuldstændig sammen og får det til at køre utroligt langsomt.

Jeg havde en sag med en rapport, der havde to komplekse forespørgsler på omkring 150 linjer hver, men som kørte på 7 sekunder i mit udviklingsmiljø - hele rapporten tog mindre end 10 sekunder. Men når rapporten blev implementeret på produktions-SSRS-serveren, tog den mere end 7 minutter og fik ofte timeout, hvilket gjorde rapporten ubrugelig.

De fleste oplysninger om dette problem taler om det i forhold til lagrede procedurer. Afvis ikke dette, fordi du ikke bruger lagrede procedurer (som jeg gjorde i lang tid); det er også meget relevant for straight Sql-forespørgsler.

Så forskellen, du ser, er, at SQL Server opretter to meget forskellige eksekveringsplaner, da de to forespørgsler er struktureret forskelligt.

Heldigvis er løsningen meget enkel:Indsæt parametrene i interne variabler og brug disse i din forespørgsel i stedet for. Jeg gjorde dette med min rapport, og produktionsrapporten gik tilbage til 10 sekunder, ligesom udviklingsversionen gjorde i Visual Studio.

For at omgå parametersniffing for din første forespørgsel, vil du få det til at se sådan ud:

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. Hvad kræver dette JavaScript?

  2. Forskellige værdier tæller i samme kolonne

  3. Sådan tilføjer du standardbegrænsning til eksisterende kolonner i SQL Server-tabel - SQL Server / TSQL selvstudium, del 91

  4. UNION-forespørgsel med kodetænderens aktive registreringsmønster