Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Tại sao truy vấn T-SQL thứ 2 chạy nhanh hơn nhiều so với truy vấn đầu tiên khi được gọi bởi Reporting Services 2005 trong một ứng dụng web

Bạn có thể đã gặp phải một truy vấn có vấn đề với việc dò tìm tham số, điều này liên quan đến cách Sql Server cố gắng tối ưu hóa kế hoạch thực thi truy vấn của bạn nhưng trong các trường hợp khi Dịch vụ báo cáo có liên quan hoàn toàn làm rối tung nó và làm cho nó chạy cực kỳ chậm.

Tôi đã gặp trường hợp với một báo cáo có hai truy vấn phức tạp, mỗi truy vấn khoảng 150 dòng nhưng chạy trong 7 giây trong môi trường phát triển của tôi - toàn bộ báo cáo chỉ mất chưa đầy 10 giây. Tuy nhiên, khi được triển khai tới máy chủ SSRS sản xuất, báo cáo mất hơn 7 phút và thường hết thời gian khiến báo cáo không thể chạy được.

Hầu hết thông tin về vấn đề này nói về nó liên quan đến các thủ tục được lưu trữ. Đừng loại bỏ điều này bởi vì bạn không sử dụng các thủ tục được lưu trữ (như tôi đã làm trong một thời gian dài); nó cũng rất liên quan đến các truy vấn Sql.

Vì vậy, sự khác biệt mà bạn đang thấy là Sql Server đang tạo hai kế hoạch thực thi rất khác nhau vì hai truy vấn được cấu trúc khác nhau.

May mắn thay, giải pháp rất đơn giản:đặt các tham số vào các biến bên trong và thay vào đó sử dụng chúng trong truy vấn của bạn. Tôi đã làm điều này với báo cáo của mình và báo cáo sản xuất quay trở lại 10 giây giống như phiên bản phát triển đã làm trong Visual Studio.

Để bỏ qua tính năng dò tìm tham số cho truy vấn đầu tiên của bạn, bạn sẽ làm cho nó trông giống như sau:

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. Cách tốt nhất để triển khai Hiệp hội đa hình trong SQL Server là gì?

  2. SQL Server - thiếu NATURAL JOIN / x JOIN y USING (trường)

  3. Hiểu rõ về các ràng buộc duy nhất của SQL Server

  4. Cách lấy tất cả các bảng có ràng buộc khóa chính được tạo trong cơ sở dữ liệu SQL Server - Hướng dẫn sử dụng SQL Server / TSQL 57

  5. Hướng dẫn hoàn chỉnh để sửa lỗi cơ sở dữ liệu SQL 5243