2016-07-22 12 views
5

tôi đã nghiên cứu porting một số mã EF6 của chúng tôi để Dapper cho hiệu suất tốt hơn khi tôi chạy vào một vấn đề lạ. Một truy vấn hàng đơn lẻ đã lấy gần gấp 10 lần số nhiều hơn trong Dapper so với EF. Nó trông giống như sau:hiệu suất Dapper Xấu cho parametrized truy vấn

using (IDbConnection conn = new SqlConnection("connection string")) 
{     
     row = conn.Query<ReportView>("select * from ReportView where ID = @ID", 
              new {ID = id})) 
            .FirstOrDefault(); 
} 

Truy vấn này nhắm mục tiêu với khoảng 80 cột và phiên bản EF sử dụng cùng một truy vấn chính xác và cùng một kiểu. Để tham khảo, đây là phiên bản EF:

row = context.ReportViews.Where(s => s.ID == id).FirstOrDefault(); 

tôi đã vào tài khoản đó truy vấn đầu tiên có thể là chậm, vì vậy tôi đã đo sau một "ấm lên" thời gian. Tôi nghĩ rằng nó có thể là một vấn đề với tái sử dụng mô hình EF, vì vậy tôi tạo ra một POCO đơn giản như là một mô hình. Không ai trong số đó làm việc. Vì vậy, tôi chơi xung quanh với nó, cố gắng những thứ khác nhau, và quyết định cố gắng sử dụng một SQL-injectiony nối SQL tuyên bố.

using (IDbConnection conn = new SqlConnection("connection string")) 
{     
     row = conn.Query<ReportView>(string.Format("select * from ReportView where ID = '{0}'", 
      id)).FirstOrDefault(); 
} 

này truy vấn đã thực sự nhanh hơn so với EF một.

Vì vậy, những gì đang xảy ra ở đây? Tại sao truy vấn parametrized chậm hơn rất nhiều?

+1

hồ sơ SQL được tạo ra – stuartd

+0

tôi đã có tất cả các loại của các vấn đề sử dụng xem với EF vì thiếu một chìa khóa tự nhiên. Tôi không chắc chắn những gì bạn xem (có thể một cái gì đó bạn không thể làm trong EF như sử dụng một CTE), nhưng tại sao không thử truy vấn trong xem thay vì xem với Dapper. – juharr

+1

Bạn đo điểm chuẩn như thế nào? – mxmissile

Trả lời

0

của nó để làm với các kiểu dữ liệu của paramater. Nếu nó không khớp với chỉ số của nó thì nó sẽ thay đổi mỗi hàng để so sánh nó. Làm như một chuỗi kiểu được chọn bởi trình phân tích cú pháp sql.

0

Dựa trên ví dụ cuối cùng của bạn, có vẻ như cột của bạn là varchar nhưng khi bạn sử dụng truy vấn tham số, tham số sẽ được gửi dưới dạng nvarchar. Kể từ khi nvarchar để varchar có thể liên quan đến mất dữ liệu, SQL chuyển đổi mỗi giá trị trong bảng để nvarchar để so sánh. Như bạn có thể tưởng tượng, chuyển đổi mỗi hàng để so sánh là chậm và ngăn chặn việc sử dụng chỉ mục.

Để làm việc xung quanh này, bạn có hai lựa chọn:

Nếu cơ sở dữ liệu của bạn không sử dụng nvarchar ở tất cả, bạn có thể chỉ cần thay đổi các bản đồ trong khởi động ứng dụng:

Dapper.SqlMapper.AddTypeMap(typeof(string), System.Data.DbType.AnsiString); 

Nếu không, bạn có thể thay đổi nó cho mỗi truy vấn:

row = conn.Query<ReportView>("select * from ReportView where ID = @ID", 
           new {ID = new DbString { Value = id, IsAnsi = true }}) 
           .FirstOrDefault(); 
Các vấn đề liên quan