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

Hiệu suất truy vấn Entity Framework khác hẳn với việc thực thi SQL thô

Trong câu trả lời này, tôi tập trung vào quan sát ban đầu:truy vấn do EF tạo ra thì chậm, nhưng khi chạy cùng một truy vấn trong SSMS thì lại nhanh.

Một giải thích có thể có về hành vi này là Đánh giá thông số .

Vì vậy, EF tạo một truy vấn có ít tham số. Lần đầu tiên bạn chạy truy vấn này, máy chủ sẽ tạo một kế hoạch thực thi cho truy vấn này bằng cách sử dụng các giá trị của các tham số có hiệu lực trong lần chạy đầu tiên. Kế hoạch đó thường khá tốt. Tuy nhiên, sau đó, bạn chạy cùng một truy vấn EF bằng cách sử dụng các giá trị khác cho các tham số. Có thể là đối với các giá trị mới của tham số, kế hoạch được tạo trước đó không tối ưu và truy vấn trở nên chậm. Máy chủ tiếp tục sử dụng kế hoạch trước đó, bởi vì nó vẫn là cùng một truy vấn, chỉ là giá trị của các tham số khác nhau.

Nếu tại thời điểm này, bạn lấy văn bản truy vấn và cố gắng chạy nó trực tiếp trong SSMS, máy chủ sẽ tạo một kế hoạch thực thi mới, vì về mặt kỹ thuật, nó không giống với truy vấn được ứng dụng EF đưa ra. Ngay cả sự khác biệt một ký tự là đủ, bất kỳ thay đổi nào trong cài đặt phiên cũng đủ để máy chủ coi truy vấn như một truy vấn mới. Kết quả là máy chủ có hai kế hoạch cho cùng một truy vấn trong bộ nhớ cache của nó. Kế hoạch "chậm" đầu tiên là chậm đối với các giá trị mới của tham số, vì ban đầu nó được xây dựng cho các giá trị tham số khác nhau. Kế hoạch "nhanh" thứ hai được xây dựng cho các giá trị tham số hiện tại, vì vậy nó rất nhanh.

Bài viết Chậm trong ứng dụng, Nhanh trong SSMS của Erland Sommarskog giải thích điều này và các lĩnh vực liên quan khác một cách chi tiết hơn.

Có một số cách để loại bỏ các kế hoạch đã lưu trong bộ nhớ cache và buộc máy chủ phải tạo lại chúng. Việc thay đổi bảng hoặc thay đổi chỉ mục bảng là điều nên làm - cần loại bỏ tất cả các kế hoạch liên quan đến bảng này, cả "chậm" và "nhanh". Sau đó, bạn chạy truy vấn trong ứng dụng EF với các giá trị mới của tham số và nhận được một kế hoạch "nhanh" mới. Bạn chạy truy vấn trong SSMS và nhận được kế hoạch "nhanh" thứ hai với các giá trị mới của tham số. Máy chủ vẫn tạo ra hai gói, nhưng cả hai gói hiện đều nhanh.

Một biến thể khác đang thêm OPTION(RECOMPILE) cho truy vấn. Với tùy chọn này, máy chủ sẽ không lưu trữ kế hoạch đã tạo trong bộ nhớ cache của nó. Vì vậy, mỗi khi truy vấn chạy, máy chủ sẽ sử dụng các giá trị tham số thực tế để tạo ra kế hoạch (nó cho rằng) sẽ là tối ưu cho các giá trị tham số đã cho. Nhược điểm là chi phí tạo kế hoạch tăng thêm.

Xin lưu ý rằng máy chủ vẫn có thể chọn một kế hoạch "xấu" với tùy chọn này do số liệu thống kê đã lỗi thời, chẳng hạn. Nhưng, ít nhất, đánh giá tham số sẽ không thành vấn đề.

Những ai thắc mắc cách thêm OPTION(RECOMPILE) gợi ý cho truy vấn được tạo bởi EF, hãy xem câu trả lời sau:

https://stackoverflow.com/a/26762756/4116017



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tôi có nên đặt kích thước nhóm tối đa trong chuỗi kết nối cơ sở dữ liệu không? Điều gì xảy ra nếu tôi không làm vậy?

  2. Làm cách nào để loại bỏ không gian tên thừa trong truy vấn lồng nhau khi sử dụng FOR XML PATH

  3. Tạo một biến tĩnh toàn cục trong SQL Server?

  4. Máy chủ SQL CHO TỪNG vòng lặp

  5. Bảng tạm thời của Sql Server biến mất