天天看點

用上這幾種.NET EF Core性能調優,查詢性能飙升

作者:中年農碼工

1、避免在循環中進行查詢操作:

避免在循環中進行查詢操作,可以将查詢結果緩存到記憶體中,然後對記憶體中的資料進行操作,可以提高性能。這種方式适合集合資料量少的資料,否則利大于弊。

// 不建議的方式:在循環中進行查詢操作
foreach (var item in itemList)
{
    var result = context.Items.FirstOrDefault(i => i.Id == item.Id);
//執行邏輯
}
// 推薦的方式:将查詢結果緩存到記憶體中,然後對記憶體中的資料進行操作
var itemIds = itemList.Select(i => i.Id).ToList();
var results = context.Items.Where(i => itemIds.Contains(i.Id)).ToList();
foreach (var item in itemList)
{
    var result = results.FirstOrDefault(r => r.Id == item.Id);
    //執行邏輯
}
           

2、避免使用懶加載:

避免使用懶加載,因為每次通路導航屬性都會觸發額外的資料庫查詢。使用顯式加載或預先加載的技術可以提高性能。

// 不建議的方式:使用懶加載
var order = context.Orders.FirstOrDefault();
foreach (var item in order.Items)
{
  //執行邏輯
}
// 推薦的方式:使用預先加載
var order = context.Orders.Include(o => o.Items).FirstOrDefault();
foreach (var item in order.Items)
{
   //執行邏輯
}
           

3、合理使用Include方法:

Include方法可以在一次查詢中擷取所有相關的實體對象。但是,當涉及到大量資料時,Include方法會導緻性能下降。可以使用手動連結查詢代替Include方法。

// 不建議的方式:使用Include方法擷取所有關聯實體
var orders = context.Orders.Include(o => o.Items).ToList();

// 推薦的方式:使用手動連結查詢代替Include方法
var orders = context.Orders
    .Join(context.OrderItems,
          o => o.Id,
          oi => oi.OrderId,
          (o, oi) => new { Order = o, OrderItem = oi })
    .ToList();
           

4、使用NoTracking方法:

使用NoTracking方法可以避免EF Core的跟蹤功能。跟蹤功能在更新和删除實體對象時非常有用,但是在隻需要讀取資料時,跟蹤功能會導緻額外的開銷。使用NoTracking方法可以禁用跟蹤功能,進而提高性能。

// 不建議的方式:使用預設跟蹤功能
var order = context.Orders.FirstOrDefault();
// 推薦的方式:使用NoTracking方法
var order = context.Orders.AsNoTracking().FirstOrDefault();
//歡迎公衆号:DOTNET開發跳槽
           

5、執行原始SQL查詢:

有些情況下,使用原始的SQL語句可以比使用EF Core更高效。使用FromSqlRaw或者ExecuteSqlRaw方法可以執行原始SQL查詢。

// 執行原始SQL查詢
var orders = context.Orders.FromSqlRaw("SELECT * FROM Orders WHERE Status = 'Complete'").ToList();
           

6、使用EF.CompileAsyncQuery

EF.CompileAsyncQuery是EF Core的一個擴充方法,它可以将LINQ表達式編譯為一個異步查詢。相比于動态生成LINQ查詢,使用EF.CompileAsyncQuery可以提高查詢性能,減少不必要的記憶體配置設定。

編譯後的查詢可以多次調用,而不必每次動态生成查詢表達式。這樣可以避免不必要的記憶體配置設定和查詢優化開銷,提高查詢性能。在EF Core 5.0及以上版本中,EF.CompileAsyncQuery已經成為了标準的擴充方法,無需進行任何特殊的安裝或配置即可使用。它适用于查詢條件固定的情況,當然也可以重新編譯,不過頻繁的編譯會造成記憶體和性能的開銷。示例如下:

using Microsoft.EntityFrameworkCore.Query;
// 定義一個異步查詢
private static readonly Func<MyDbContext, int, Task<Order>> GetOrderById =
    EF.CompileAsyncQuery((MyDbContext context, int id) =>
        context.Orders.FirstOrDefaultAsync(o => o.Id == id));
// 調用異步查詢
var order = await GetOrderById(context, 1);
           

結語

本文講述了6種性能調優的方式,希望對大家有所幫助,尤其是面試的時候,當面試官問您有沒有什麼辦法提高EF Core的性能,大家可以回答其中幾個。當然上面的方法不是絕對的,需要根據實際場景來應用,比如Include方法在資料量小的情況下适合使用,資料量大的話就适得其反了。大家還有什麼EF Core調優的方法,歡迎留言讨論或者吐槽本文。

用上這幾種.NET EF Core性能調優,查詢性能飙升

繼續閱讀