Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Защо втората T-SQL заявка работи много по-бързо от първата, когато е извикана от Reporting Services 2005 в уеб приложение

Може да сте попаднали на заявка, която има проблем с подслушването на параметри, което е свързано с начина, по който 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;



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. .NET 4:Как да конфигурирате EDMX файл в друг сборник в Web.Config

  2. Търсенето на пълен текст не работи, ако е включена спираща дума, въпреки че списъкът със стоп думи е празен

  3. Създайте база данни на SQL Server с SQLOPS

  4. Разлика между подзаявка и корелирана подзаявка

  5. Как да променя SQL Server 2005 така, че да е чувствителен към главни букви?