我正在使用Entity 6和PostgreSQL数据库(带有Npgsql连接器)。一切都很好,除了这个设置的性能很差。当我尝试向数据库中插入数量不是很大的对象(大约20k条记录)时,它花费的时间比正常情况下要多得多。由于这是我第一次使用实体框架,我很困惑为什么将20k记录插入到我本地机器上的数据库需要1分钟以上的时间。
为了优化插入,我遵循了我找到的每一个技巧。我尝试将AutoDetectChangesEnabled设置为false,每100或1000条记录调用SaveChanges(),重新创建数据库上下文对象并使用DbContextTransaction对象(通过调用dbContext.Database.BeginTransaction()并在操作结束时或每100/1000条记录提交事务)。没有任何改进会增加性能,哪怕只是一点点。
通过记录Entity生成的SQL查询,我终于能够发现,无论我做什么,每个对象都是单独插入的,每次插入都需要2-4毫秒。在没有重新创建DB上下文对象和事务的情况下,在超过20k的插入之后只有一次提交。当我使用事务并每隔几条记录提交一次时,会有更多的提交和新的事务创建(当我重新创建DB上下文对象时也是如此,只是重新建立了连接)。如果我使用事务并每隔几条记录提交一次,我应该会注意到性能提升,不是吗?但是,无论我是否使用多个事务,最终在性能上都没有区别。我知道事务不会显著提高性能,但它们至少应该有一点帮助。取而代之的是,在我的本地DB上,每次插入仍然需要至少2ms的执行时间。
在本地机器上创建数据库是一回事,但在远程数据库上创建20k对象需要的时间比一分钟要长得多-日志表明,单次插入可能需要30毫秒(!),事务每100或1000条记录提交并重新创建一次。另一方面,如果我手动执行一次插入(直接从日志中获取),执行时间不到1ms。尽管Entity使用事务将大量的插入内容包装在一起,但将每个对象都插入到数据库中似乎也是从容不迫的。我真的不明白...
我能做些什么来真正加速它呢?
发布于 2017-04-19 06:20:38
如果有人感兴趣,我找到了我的问题的解决方案。Entity Framework6在没有额外的第三方库的情况下无法提供快速的批量插入(正如我的问题的注释中所提到的),这些库要么很昂贵,要么不支持SQL Server以外的其他数据库。另一方面,实体框架核心则是另一回事。它支持快速批量插入,只需对代码进行一些更改即可在项目中替换EF6:https://docs.microsoft.com/pl-pl/ef/core/index
https://stackoverflow.com/questions/43474912
复制相似问题