2013-03-23 39 views
18

Gần đây tôi đã chuyển mô hình thực thể của mình từ một ObjectContext sử dụng 4.1 sang DbContext bằng 5.0. Tôi bắt đầu hối tiếc vì tôi nhận thấy một số hiệu suất rất kém trên truy vấn bằng cách sử dụng DbContext vs ObjectContext. Đây là kịch bản thử nghiệm:DbContext Hiệu suất truy vấn kém so với ObjectContext

Cả hai ngữ cảnh đều sử dụng cùng một cơ sở dữ liệu với khoảng 600 bảng. LazyLoading và ProxyCreation được tắt cho cả hai (không được hiển thị trong ví dụ mã). Cả hai đều có lượt xem được tạo trước.

Lần kiểm tra đầu tiên thực hiện 1 cuộc gọi để tải lên vùng làm việc siêu dữ liệu. Sau đó, trong vòng lặp for được thực hiện 100 lần, tôi mới tạo ra một ngữ cảnh và thực hiện một cuộc gọi đầu tiên. 10. Tôi đang tạo ngữ cảnh bên trong vòng lặp for bởi vì mô phỏng này được sử dụng trong dịch vụ WCF. bối cảnh mỗi lần)

for (int i = 0; i < 100; i++) 
{ 
    using (MyEntities db = new MyEntities()) 
    { 
     var a = db.MyObject.Take(10).ToList(); 
    } 
} 

Khi tôi chạy điều này với ObjectContext mất khoảng 4,5 giây. Khi tôi chạy nó bằng DbContext, nó mất khoảng 17 giây. Tôi đã lược tả điều này bằng cách sử dụng trình biên dịch hiệu suất của RedGate. Đối với DbContext có vẻ như thủ phạm chính là một phương thức gọi là UpdateEntitySetMappings. Điều này được gọi trên mọi truy vấn và xuất hiện để truy xuất metadataworkspace và chuyển qua tất cả các mục trong không gian OS. AsNoTracking không giúp được gì.

EDIT: Để cung cấp cho một số chi tiết tốt hơn, vấn đề phải làm với việc tạo \ khởi tạo của một DbSet vs một ObjectSet, không phải là truy vấn thực tế. Khi tôi thực hiện cuộc gọi với ObjectContext, phải mất trung bình 42ms để tạo ObjectSet. Khi tôi thực hiện cuộc gọi với DbContext, phải mất khoảng 140ms để tạo dbset nội bộ. Cả hai ObjectSet và DbSet thực hiện một số thực thể lập bản đồ tra cứu từ metadataworkspace. Những gì tôi đã nhận thấy là DbSet hiện nó cho tất cả các loại trong không gian làm việc trong khi ObjectSet thì không. Tôi đoán (chưa thử nó) rằng một mô hình có ít bảng hơn sự khác biệt về hiệu suất là ít hơn.

Trả lời

2

DbContext là trình bao bọc cho ObjectContext. Đây là câu hỏi hay về số answer của bạn. Có thể là để sử dụng dễ dàng hơn, họ đã hy sinh hiệu suất.

-3

Tôi sử dụng Simple.Data để truy vấn hàng triệu bản ghi và hoạt động khá tốt và nhanh chóng.

4

Tôi cũng được quan tâm bởi sự kém hiệu quả của các phương pháp mã đầu tiên và tôi đã thực hiện một số tiêu chuẩn trong một kịch bản tương tự như của bạn

http://netpl.blogspot.com/2013/05/yet-another-orm-micro-benchmark-part-23_15.html

Kết quả thật không ngạc nhiên, kể từ khi DbContext là một wrapper trên ObjectContext, nó phải hy sinh hiệu suất cho sự đơn giản. Tuy nhiên, thử nghiệm của tôi cho thấy rằng:

  • các hồ sơ nhiều bạn lấy lại ít được sự khác biệt
  • các hồ sơ nhiều bạn lấy lại quan trọng hơn đó là tắt theo dõi nếu bạn muốn trở thành nhanh hơn

Ví dụ, lấy chỉ 10 hồ sơ

enter image description here

Lưu ý mã mà đầu tiên là chậm hơn so với cách đáng kể mô hình đầu tiên và không có sự khác biệt đáng chú ý giữa theo dõi và không theo dõi - cả hai quan sát giống hệt nhau của bạn.

Tuy nhiên khi lấy 10000 hàng bạn có

enter image description here

Lưu ý rằng hầu như không có sự khác biệt giữa các mã đầu tiên và mô hình đầu tiên trong phiên bản notracking. Ngoài ra, cả hai thực hiện đáng ngạc nhiên tốt, gần như nhanh như datareader ado.net thô.

Hãy làm theo mục nhập blog của tôi để biết thêm chi tiết.

Điểm chuẩn đơn giản đó đã giúp tôi chấp nhận bản chất của mã đầu tiên. Tôi vẫn thích nó cho các dự án nhỏ hơn vì hai tính năng: thực thể poco và di chuyển. Mặt khác, tôi sẽ không bao giờ chọn bất kỳ một trong hai cho một dự án mà hiệu suất là một yêu cầu quan trọng. Điều này có nghĩa là tôi sẽ không bao giờ sử dụng phương pháp tiếp cận đầu tiên của mô hình nữa.

(Lưu ý: điểm chuẩn của tôi cũng tiết lộ rằng có điều gì đó sai với nHibernate. Tôi vẫn chưa tìm thấy ai để giúp tôi giải thích điều này mặc dù tôi đã tư vấn hai nhà phát triển độc lập sử dụng NH hàng ngày)

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