Zap*_*ica 1 c# sql entity-framework bulkinsert insert
我有一个应用程序,它从多个套接字接收数据,然后将数据写入数据库。
我目前正在使用 EF 来执行此操作。我想知道如何才能提高效率。
我读到,批量插入速度更快,所以我只每 500 个插入保存对数据库的更改:
db.Logs_In.Add(tableItem);
if (logBufferCounter++ > 500)
{
db.SaveChanges();
logBufferCounter = 0;
}
Run Code Online (Sandbox Code Playgroud)
现在我已经分析了应用程序,74% 的工作是由该函数完成的:System.Data.Enitity.DbSet'1[System._Canon].Add
有没有更好的方法来进行插入?也许将表项排队到列表中,然后将整个列表添加到数据库上下文中。
或者也许我看错了,我应该完全避免使用 EntityFramework 来实现更高性能的插入?目前它是我的应用程序中的瓶颈,如果我查看系统资源,SQL 似乎根本没有动过眼睛。
所以我的问题:
1:如何在多次插入中实现最高效/最快的插入
2:如果EF可以接受,我该如何改进我的解决方案?
我使用的是 SQL Server 2012 企业版,传入的数据是恒定的流,但是我可以缓冲它,然后执行批量插入(如果这是更好的解决方案)。
[编辑]
进一步解释该场景。我有一个线程在并发队列上循环,该线程使该队列中的项目出列。然而,由于数据库插入是瓶颈。队列中通常有数千个条目,因此,如果还有一种异步或并行方式,我可能会利用多个线程来执行插入。
对于涉及大量插入的场景,我倾向于“单独缓冲”(在内存中,或redis列表,或其他什么),然后作为批处理作业(可能每分钟或每几分钟)读取列表并用于SqlBulkCopy尽可能有效地将数据放入数据库中。为了解决这个问题,我使用fastmemberObjectReader.Create的方法,它将 a (或任何)公开为可以输入到 中的an ,将 的属性公开为数据读取器中的逻辑列。那么,您需要做的就是从缓冲区中填充。List<T>IEnumerable<T>IDataReaderSqlBulkCopyTList<T>
但请注意,您需要考虑“出现问题”的情况;即,如果插入中途失败,您将如何处理缓冲区中的数据?SqlBulkCopy这里的一种选择是对临时表(相同的架构,但不是“实时”表)进行操作,然后INSERT当您知道数据位于数据库时使用常规方法一步复制数据 - 这使得恢复更简单。