簡體   English   中英

EF SaveChangesAsync非常慢

[英]EF SaveChangesAsync extremely slow

我有一個表,我想一次更新100行。 我列出了用於查找特定行的100個ID。 找到后,我為每一行更新一列(SyncOk)。

問題是更新100行大約需要23到30秒

dbContext.Configuration.ValidateOnSaveEnabled = false;
var count = ids.Count;
for (var i = 0; i < count; i++)
{
    var id = ids[i];
    var record = await dbContext.History
        .FirstOrDefaultAsync(r => r.Id == id);
    record.SyncOk = syncOk;
}
await dbContext.SaveChangesAsync();

一些注意事項:

  • ids是一個IList<long> ,其中包含所有感興趣的ID。
  • syncOk是一個布爾值。
  • 我嘗試將AutoDetectChangesEnabled屬性設置為false,然后在設置SyncOk值后SyncOk手動更新記錄-不會加快速度。

為什么SaveChangesAsync()這么慢- 如何提高上述功能的速度? 恐怕該表在23到30秒內被鎖定,並且會使其他服務(使用同一表)也無法更新它。

您正在執行的ids.Count總數為數據庫ids.Count SELECT語句。 如果添加代碼,則可以看到:

dbContext.Database.Log += Console.WriteLine;

通過一次獲取所有數據,嘗試最小化對SQL實例的訪問:

var records = await dbContext.History.Where(i => ids.Contains(i.Id)).ToListAsync();

然后,您應該執行所需的修改:

foreach(var record in records)
{
    record.SyncOk = syncOk;
}
await dbContext.SaveChangesAsync();

您也可以使用ForEachAsync ,該查詢將只查詢一次上述代碼部分的結果:

await dbContext.History.Where(i => ids.Contains(i.Id))
                       .ForEachAsync(i => i.SyncOk = syncOk);
await dbContext.SaveChangesAsync();

恕我直言, Select * from History where Id in (YourList)下面的Select * from History where Id in (YourList)中執行Select * from History where Id in (YourList)

var listOfRecordsToBeUpdated = await dbContext.History
        .Where(r => ids.Contains(r.Id)).ToListAsync();

//It will detect the changes each time when you update the entity
// Make sure you re-enable this after your bulk operation
DataContext.Configuration.AutoDetectChangesEnabled = false;

//Iterate through the records and assign your value
listOfRecordsToBeUpdated.Foreach(x=>x.SyncOk = syncOk);

DataContext.Configuration.AutoDetectChangesEnabled = true;

await conn.SaveChangesAsync();

通過禁用AutoDetectChangesEnabled提高性能

我嘗試實現其他兩個答案建議的更改-但是具有相同的性能結果(即,速度沒有變化)。

通過使用原始SQL命令,我極大地提高了性能(並解決了我的問題):

var stringOfIds = string.Join(",", ids);
await dbContext.Database.ExecuteSqlCommandAsync(
    $"UPDATE dbo.History SET SyncOk = 1 WHERE Id IN ({stringOfIds})");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM