实体6 + PostgreSQL - 可怕的性能

实体6 + PostgreSQL - 可怕的性能

问题描述:

我使用实体6与PostgreSQL数据库(使用Npgsql连接器)。一切工作正常,除了这种设置性能差。当我尝试向数据库中插入不是很多的对象时(大约20k条记录),它需要比它应该多得多的时间。由于这是我第一次使用实体框架,我很困惑为什么在我的本地机器上插入20k记录到数据库将花费1分多钟。实体6 + PostgreSQL - 可怕的性能

为了优化插入我跟随我找到的每个提示。我尝试将AutoDetectChangesEnabled设置为false,每100或1000条记录调用SaveChanges(),重新创建数据库上下文对象并使用DbContextTransaction对象(通过在操作结束时调用dbContext.Database.BeginTransaction()和提交事务或每100/1000记录)。即使一点点也没有改善插入性能。

通过记录由实体生成的SQL查询,我终于能够发现无论我做什么,每个对象都是分开插入的,每个插入需要2-4毫秒。如果不重新创建数据库上下文对象并且没有事务,则在超过20k次插入后只有一次提交。当我使用事务并提交每几条记录时,会有更多的提交和新的事务创建(当我重新创建数据库上下文对象时也是如此,只需重新建立连接)。如果我使用交易并提交每一条记录,我应该注意到性能提升,不是吗?但最后,无论是否使用多次交易,效果都没有差异。我知道交易不会大幅提升业绩,但他们至少应该有所帮助。相反,每个插入仍然需要至少2ms才能在本地数据库上执行。

本地机器上的数据库是一回事,但在远程数据库上执行20k对象的创建需要很多很多很多时间超过一分钟 - 日志表明单个插入可能需要甚至30ms(!),而事务被提交并且每100或1000条记录重新创建一次。另一方面,如果我手动执行一次插入(从日志中直接获取),则执行时间不到1毫秒。看起来Entity将每一个对象都插入数据库的时间很短,尽管它使用事务来将大量的插入操作放在一起。我真的不明白...

我能做些什么来加速它的真实性?

+1

有人可能会对此做进一步阐述,但EF不适用于批量插入。 –

+0

EF无法帮助您开箱即用。有一些第三方库在EF之上实现批量插入。 –

+0

我的客户端和数据库服务器之间的ping如何?另外,您是否使用连接池软件? –

如果有人有兴趣,我找到了解决我的问题。如果没有额外的第三方库(如我的问题的评论中所述),实体框架6无法提供快速批量插入,这些插入既昂贵又不支持除SQL Server之外的其他数据库。另一方面,实体框架核心是另一回事。它支持快速大容量插入,并且可以替换工程中的EF 6,只需对代码进行一系列更改:https://docs.microsoft.com/pl-pl/ef/core/index

+0

没错,但是在这个时候,ef-core还不能完全取代ef6,这就是为什么我是警惕地暗示它。 –