关于EF Core 更新速度随时间越来越慢的解决办法

这篇具有很好参考价值的文章主要介绍了关于EF Core 更新速度随时间越来越慢的解决办法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

关于EF Core更新速度随时间越来越慢的解决办法

概要

本篇主要介绍使用 context.ChangeTracker.Clear() 方法,在通过循环进行批量更新时,通过手动清除跟踪实体以提高性能的示例。

背景

最近在做一些数据分析时,遇到了一个问题,当我把计算结果更新到数据库时,一开始速度会很快,但随着时间的推移,更新速度会越来越慢。
本篇博客就来说明这种现象的原因和解决办法。

环境:ASP.NET Core 7EF Core 7.

事例说明

我有1000W已处理好的数据需要更新到数据库,这些数据我也是从数据库中一次性查询出来的,这样可以只进行一次查询,并使用AsNoTracking()提高查询效率,然后我对这些数据进行了并行计算,最后将计算完的结果更新到数据库。最费时的操作就是更新到数据库。

请看以下代码示例:

var bc = new ConcurrentBag<List<StockDailyKLineInfo>>();
// 并行计算
var computeTasks = group.AsParallel()
    .WithDegreeOfParallelism(Environment.ProcessorCount)
    .WithExecutionMode(ParallelExecutionMode.ForceParallelism)
    .Select(async g =>
    {
        var computedData = await service.ComputeAsync(g.ToList());
        if (computedData != null)
        {
            bc.Add(computedData);
        }
    });

await Task.WhenAll(computeTasks);

// 数据插入
var batchSize = 5000;
var items = bc.SelectMany(x => x).ToList();
left = items.Count;
_logger.LogInformation($"need update {left} daily!");

foreach (var batch in items.Chunk(batchSize))
{
    context.AttachRange(batch);
    foreach (var entity in batch)
    {
        var entry = context.Entry(entity);
        entry.Property(e => e.A).IsModified = true;
        entry.Property(e => e.B).IsModified = true;
        entry.Property(e => e.C).IsModified = true;
        entry.State = EntityState.Modified;
    }

    var count = await context.SaveChangesAsync();
}
await Console.Out.WriteLineAsync("[done] update all data");

并行计算速度非常快,几秒就能都完成了。

数据插入,我分批进行循环插入,每次5000条,通常不到1秒时间就能插入成功。但随着时间的推移,插入速度越来越慢。

[!NOTE]
由于我有1000W的数据插入,如果最终一次性提交,如果出现了异常,那么所有数据都不会插入成功,并且会等待很长的时间,并且在最终执行完成之前,你得不到任何信息,以预估可能花费的时间。所以我需要分批插入。

原因

EF Core 会在上下文中跟踪所有已加载或附加的实体。随着循环的进行,上下文将追踪越来越多的实体,这可能会导致性能下降。

也就是说在同一个DbContext上下文中,SaveChangesAsync()方法调用后,不会清除已更新的内容,这意味着追踪的实体越来越多,最终多达1000W,并且这些都是已经标记为要更新的内容,也意味着你每次都会更新更多的内容到数据库。

解决办法

只进行一次SaveChanges

既然每次saveChanges不会清除,那么最后我只提交一次不就行了么?但这个方案不符合实际需求,上面已经提到过了。

使用多个DbContext

既然 同一个DbContext下会出现这个问题,那么每次更新,我再创建一个新的DbContext不就可以了么?
这个方法虽然可行,但对于1000W的数据来说,即使我每次更新1W条数据,也需要创建1000+次DbContext,也有一定的消耗。

清除追踪

既然问题是SaveChanges不会自动清除已追踪的更改,如果我可以手动去清除,不就可以了么?清除的操作比起创建新的DbContext实例,还是更快捷的。

那么我们修改代码:

foreach (var batch in items.Chunk(batchSize))
{
    context.AttachRange(batch);
    foreach (var entity in batch)
    {
        var entry = context.Entry(entity);
        entry.Property(e => e.A).IsModified = true;
        entry.Property(e => e.B).IsModified = true;
        entry.Property(e => e.C).IsModified = true;
        entry.State = EntityState.Modified;
    }
    var count = await context.SaveChangesAsync();

    // ⚒️ add this line
    context.ChangeTracker.Clear();
}

[!TIP]
context.ChangeTracker.Clear() 方法清除上下文中的所有已跟踪实体。这将重置更改跟踪器并清除其跟踪的所有实体,从而释放内存并提高性能。

总结

EF Core 7 中已经添加了批量更新的方法,但这种方法也不适用于我遇到的场景,因为我不是按条件进行批量更新,而是每一条数据都需要更新。
context.ChangeTracker.Clear()可以在这样的场景下发挥作用,在一些关联插入或更新的场景,为避免追踪带来的冲突问题,也可以通过该方法清除追踪,然后再手动建立关系,进行提交。文章来源地址https://www.toymoban.com/news/detail-500987.html

到了这里,关于关于EF Core 更新速度随时间越来越慢的解决办法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 为什么越来越多的企业选择云计算

    目录 一、前言 二、云计算的基础概念 2.1 云计算的定义 2.2 云计算的发展历程 2.3 云计算的基本架构 三、 企业采用云计算的优势 四、 行业应用案例 五、未来发展与挑战 六、总结 随着数字化转型的加速,越来越多的企业开始选择云计算作为信息技术应用的基础设施。那么,

    2024年02月02日
    浏览(64)
  • 越来越看不懂的企业数字化转型……

    近日和一做乙方的老友相聚谈起了今年的企业数字化转型情况,都有一个整体的感受那就是: 越来越看不懂了,有价无市,看似热闹,实则观望。   经历几年疫情,行业内都普遍认为企业领导对于数字化的重视程度在提高,毕竟数字化的技术能力及所取得的成果在这两年是

    2024年02月13日
    浏览(55)
  • mac电脑储存内存越来越小如何清理释放空间?

    如果你是一位Mac系统的用户,可能会发现你的电脑储存空间越来越小。虽然Mac系统设计得非常优秀,但是系统数据和垃圾文件也会占据大量的储存空间。在这篇文章中,我们将探讨mac系统数据怎么这么大,以及mac清理系统数据怎么清理。 一、mac系统数据怎么这么大 许多Mac用

    2024年02月08日
    浏览(61)
  • 加密越来越简单——用JavaScript实现数据加密和解密

    在当今互联网的世界中,安全性越来越受到关注,数据加密成为了必不可少的一环。Javascript作为前端开发的主要语言之一,也有着重要的加密应用。本篇博客将讨论Javascript加密的概念、常用算法以及代码示例。 Javascript加密 ,简单来说就是通过Javascript实现数据的加密和解密

    2024年02月15日
    浏览(64)
  • Edge浏览器越来越难用了?又惹“众怒”!

    最近,Edge浏览器进行正式开始推送v111稳定版更新,这可把我们很多企业用户恶心坏了。 该版本在界面通过右上角,添加了我们一个企业非常没有突兀碍眼、不协调的Bing按钮。 更糟糕的是,微软没有提供隐藏选项,所以你不能只是移除禁用。 对于一个集成的这个必应聊天,

    2024年02月05日
    浏览(50)
  • IPV6使用越来越广,您会配置吗?

    前面针对IPv6写过一篇文章,但是好多网友反映没有读懂,今天再给大家把内容浓缩一下,教给大家如何配置。 IPV6的推出主要是为了解决地址空间的不足,从而进一步的促进互联网的发展。IPV6地址空间大到惊人,有人比喻地球上的每粒沙子都可以拥有一个IPv6地址。   128bit的

    2024年02月13日
    浏览(52)
  • 为什么越来越多公司开始用低代码开发?

    时代洪流的走向,我们无法左右,能够把握的,只有做好自己。如何在寒冬来之不易的机会中,生存并且壮大。 不知道大家有没有发现,今年的低代码赛道异常火热,但火热的背后才值得思考,市场需求持续被挖掘,是什么造就了目前诸多低代码平台的井喷? 在低代码应用

    2024年02月04日
    浏览(64)
  • 为什么越来越多的企业开始选择云计算?

    一、前言 随着数字化时代的到来,企业对于数据的需求越来越大,而传统的数据存储方式已经无法满足企业的需求。云计算作为一种新兴的技术,可以为企业提供更加灵活、高效、安全的数据存储和处理方式,因此越来越多的企业开始选择云计算。 云计算可以帮助企业降低

    2024年02月08日
    浏览(67)
  • 为什么电脑运行越来越慢?解决方法又是什么呢?

    如果您经常使用电脑,肯定遇到过这种情况:对于新购买或者新安装了操作系统的电脑,它可以很顺畅地运行,速度也很快,但随着使用时间的增长,它的整体性能不断下降,速度越来越慢。 发生这种情况,除了电脑的使用年限过长、确实应该被淘汰以外,很大可能是“操作

    2024年02月08日
    浏览(68)
  • 为什么无人机现在运用的越来越广泛呢?

    随着科技的飞速发展,无人机已经逐渐从科幻梦想走进现实,成为我们生活中不可或缺的一部分。它们不仅改变了我们的生活方式,还带来了无尽的惊喜与可能性。今天,让我们一起来探讨无人机的魅力与前景吧! 航拍美景: 无人机配备了高清摄像头,可以轻松捕捉到那些

    2024年04月08日
    浏览(96)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包