该程序通过 VK API(平均 20-50 个线程)解析用户并在数据库中创建条目。每个用户平均有20个群组,500张照片,200个好友。我在不同的表中保存朋友、群组、用户和照片的记录。总的来说,为了保存第一个用户,我向数据库发出了大约 721 个插入请求。这是每分钟 200-300 个用户 - ~ 216,000 个对数据库的插入请求。因此,通话context.SaveChanges()大约需要 6-10 分钟才能完成。
我尝试使用上下文池 - bulk insert,平均时间为 4-6 分钟。
AutoDetectChangesEnabled = false;或context.AddRange()给出大致相同的结果。
我想到的唯一快速解决方案是对用户数据进行二进制序列化并将其存储在 中byte[],这样每个用户就有 4 个插入请求。这将调用时间减少context.SaveChanges()到 1.2 秒。但随之而来的是一个自然的问题 - 为了至少为用户改变一些东西,有必要反序列化和序列化他的所有数据。
告诉我,在不使用序列化的情况下保存适用于这种情况的大量数据的方法是什么?
无需在每次打喷嚏时调用 context.SaveChanges()。
在 1 个 context.SaveChanges() 中插入 1000 条记录 比在每个记录上调用 context.SaveChanges()更快。
如果您有一些复杂的逻辑,那么最好将此逻辑移动到存储过程中。
如果数据库和应用程序在不同的机器上,那么检查网络速度可能是值得的。
大量的索引会减慢堆栈的速度。
插入时完全拒绝EF,通过BulkCopy引导这个业务。
比如你把所有的东西批量填到服务器上的某个表中,然后JOB每5分钟查询一次这个表,并添加工作表的信息。
尽管如此,查看 EF 形成的请求也无妨。
也许它们不是最优的,您应该尝试使用 LINQ。
我建议您通过 BulkCopy(最快的多次插入方式)测量数据库的填充情况,然后您将获得您应该流式传输到的值以及您不会使用 EF 跳转的值。