我正在使用带有PostgreSQL数据库的实体6(带有Npgsql连接器)。一切正常,除了这个设置的不良性能。当我尝试将不太大量的对象插入数据库(大约20k记录)时,它需要的时间比它应该多得多。由于这是我第一次使用Entity Framework,我很困惑为什么在本地计算机上将20k记录插入数据库需要1分钟以上。
为了优化插入,我按照我发现的每个提示进行了操作。我试图将AutoDetectChangesEnabled设置为false,每100或1000条记录调用SaveChanges(),重新创建数据库上下文对象并使用DbContextTransaction对象(通过调用dbContext.Database.BeginTransaction()并在操作结束时或每100个时间提交事务/ 1000条记录)。没有任何改进的插件性能甚至一点点。
通过记录实体生成的SQL查询,我终于能够发现无论我做什么,每个对象都是分开插入的,每个插入需要2-4毫秒。无需重新创建数据库上下文对象和没有事务,在超过20k次插入后只有一次提交。当我使用事务并提交每一条记录时,会有更多的提交和新的事务创建(当我重新创建DB上下文对象时,同样重新建立连接)。如果我使用事务并将它们提交给每一条记录,我应该注意到性能提升,不是吗?但最终,无论我是否使用多个交易,性能都没有差别。我知道交易不会大幅改善性能,但它们至少应该有所帮助。相反,每个插入仍然需要至少2毫秒才能在我的本地数据库上执行。
本地计算机上的数据库是一回事,但在远程数据库上执行20k对象的创建需要花费很多时间,超过一分钟 - 日志表明单个插入可能需要30ms(!),事务被提交和创建再次每100或1000条记录。另一方面,如果我手动执行单个插入(从日志中直接执行),则执行时间不到1毫秒。似乎Entity花了很多时间将每个对象插入数据库,即使它使用事务将大量插入包装在一起。我真的不明白......
我可以做些什么来加速真实?
答案 0 :(得分:2)
如果有人感兴趣,我找到了解决问题的方法。实体框架6无法提供快速批量插入而无需额外的第三方库(如我的问题的评论中所述),这些库要么昂贵,要么不支持除SQL Server之外的其他数据库。另一方面,实体框架核心是另一个故事。它支持快速批量插入,只需在代码中进行一系列更改即可替换项目中的EF 6:https://docs.microsoft.com/pl-pl/ef/core/index