6

Tôi đang sử dụng MVC3, ASP.NET 4.5, LINQ to Entities, EF5 và SQL Server 2008 R2 và Azure (để phát trực tiếp).Vấn đề hiệu suất ban đầu với LINQ to Entities khi sử dụng các loại TPH & complex, Pregen Views dường như không làm gì cả?

Tôi đang tạo tệp csdl, edml, msl và ssdl cho Mô hình trong một Dự án mẫu riêng biệt.

Các tệp này được tạo bởi nhà phát triển Entity từ Devart, nơi tôi quản lý mô hình tổ chức của mình.

Target: Entity Framework 5

  • Lazy Chở Hàng: Enabled
  • Xem Generation: Đúng
  • Validation trên xây dựng: True
  • Metadata Artifact chế biến: Nhúng trong Output hội
  • ObjectContext là đã sử dụng
  • Tạo đối tượng proxy nội dung Đã bật: đúng.

Tôi đã thực hiện thừa kế TPH trong mô hình thực thể của mình, nhờ đó lớp con cũng được tạo thành tối đa 10 loại phức hợp (CTn).

Animal<-Cat(CT1,CT2,CT3 etc) (for example) 

Mỗi loại phức tạp ánh xạ tới cột trong Bảng động vật chung.

LINQ ban đầu của tôi là:

if (db.Animal.OfType<Cat>().Any(a => a.OwnerId == myOwnerId)) 

Khi điều này được chạy lần đầu tiên, nó có thể mất khoảng 40 giây để hoàn thành. Chạy liên tiếp mất khoảng 200ms.

Khi tôi phân tích này tiếp tục sử dụng một ORM Profiler, nó mang lại cho tôi mã LINQ như:

Cat.MergeAs(0).Any(a => a.OwnerId == ((Nullable<int>)myOwnerId)) 

tôi phát hiện ra một câu hỏi tuyệt vời SO tại địa chỉ: Related SO Question, nhưng nó không đi sâu đủ. Trong khi nó đề xuất nâng cấp lên EF6, nó không đề cập đến vấn đề EF6 mới của việc phải JIT thời gian chạy EF vào lần sử dụng đầu tiên do nó nằm ngoài thời gian chạy .NET ngay bây giờ. Có lẽ trong một phiên bản sau của EF6 tức là 6.1.2 điều này được giải quyết.

Khi T-SQL được tạo bởi EF, nó chạy, theo đúng nghĩa của nó, rất nhanh. Tôi đã thử nghiệm điều này trong SSMS.

Vì vậy, câu hỏi của tôi, tính đến tháng 11 năm 2014, được tạo thành từ:

1) Làm thế nào tôi có thể giải quyết chậm trễ tải ban đầu cho TPH/kịch bản Loại Complex của tôi, có cố gắng xem pregenerated. Tôi đã thấy các tham chiếu đến "Truy vấn được biên dịch".

2) Có lẽ tôi nên nâng cấp lên EF6? Tuy nhiên, nếu tôi làm, bây giờ có một hình phạt JIT cho bản thân thời gian chạy EF, và làm thế nào tôi nên giải quyết vấn đề này. Tôi triển khai vào các trang web Azure.

3) Cuối cùng tôi phát hiện ra rằng các truy vấn đơn giản hơn khác được hưởng lợi từ các chế độ xem được tạo trước, vì vậy tôi đang sử dụng chúng. Nó chỉ dành cho bộ gõ kiểu TPH/Complex này không có tác động. Có những tình huống mà lượt xem pregen không có tác động không?

4) Có thể 3) là do thời gian được thực hiện để "tự động dịch một truy vấn" mà EF5 hiện có thể thực hiện. Sau khi đã phát triển Chế độ xem, tôi đoán đây là nút cổ chai tiếp theo. Có lẽ tính năng "tự động dịch" này cho các thực thể phức tạp như tôi mất một thời gian dài, vì vậy một người có thể thực hiện biên dịch chủ động bằng tay? Quess đây là cái mà người ta gọi là "CompiledQuery". Có liên quan để viết mã bổ sung này hay EF6x có giúp tôi ở đây không? Tôi có một linh cảm mạnh mẽ rằng bước biên dịch truy vấn này là nút cổ chai, nhưng cũng nhận ra rằng việc viết các truy vấn được biên dịch cũng không nhất thiết là giải pháp dễ dàng và dễ bảo trì nhất. Hiện tại, chúng tôi có một công việc khởi động định kỳ chỉ làm ấm tất cả các thực thể phức tạp này, vì vậy người dùng đi thẳng vào "chế độ thực hiện truy vấn ấm".

Bất kỳ trợ giúp nào ở trên sẽ được đánh giá cao.

EDIT1

Tôi vừa sử dụng dotTrace Hồ sơ JetBrains của mà đi sâu hơn nhiều, và có vẻ như để khẳng định rằng nút cổ chai của tôi đang xảy ra với:

System.Data.Query.PlanCompiler.PreProcessor.Process(Dictionary[EdmFunctionEdmProperty[]]&) 

On hit đầu tiên, nó dành 99% số thời gian ở đây, xác nhận quan điểm của tôi rằng nó là một cái gì đó để làm với thế hệ kế hoạch truy vấn. Làm thế nào tôi giải quyết vấn đề này là một vấn đề khác.

EDIT2

Tôi sẽ kiểm tra trên EF 6.1.2 sau khi một số lời khuyên tốt và đã tiếp nhiên tuyệt vời Julie Lerman về Pluralsight.

Trả lời

1

Tôi gặp sự cố tương tự và đã thử nhiều cách tiếp cận để cải thiện hiệu suất 'lần truy cập đầu tiên'.

Bạn đã từng nghĩ về việc triển khai IProcessHostPreloadClient để đặt trước bộ nhớ cache và thực hiện cuộc gọi ban đầu, thông qua mô hình Khung thực thể, đến cơ sở dữ liệu của bạn?

Giải pháp này làm việc cho tôi và tôi đã tạo ra một mẫu PreWarmCache lớp dưới đây:

namespace MyNamespace 
{ 
    public class PreWarmCache : IProcessHostPreloadClient 
    { 
     private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger(); 
     private readonly SystemRepository _systemRepository = new SystemRepository(); 

     public void Preload(string[] parameters) 
     { 
      // Perform initialization and cache loading logic 
      Logger.Debug("Application Started: {0}", _systemRepository.InitAppliation() ? "DB response OK" : "DB response failed"); 
     } 
    } 
} 

Check-out this blog để biết chi tiết về cách treo này lên đến cung cấp AutoStart của bạn trên IIS.

+0

cảm ơn vì điều này. Tôi sẽ thử cái này. Tôi chạy một chuỗi khởi động, được gọi là Pingdom, để đảm bảo đối tượng này vẫn nóng. Không lý tưởng, nhưng nó thực hiện công việc. – SamJolly

Các vấn đề liên quan