C# 在EF6中执行StoredProcedure需要花费大量的时间
我正在ASP.NET MVC5中运行EF6(v6.2.0) 当通过EF6的SqlQuery()函数执行某个StoredProcess时,我必须等待大约2分钟(!)才能在内存中获得结果 由于一些复杂的计算,StoredProcedure在数据库中大约需要9-12秒,并使用11个参数调用:C# 在EF6中执行StoredProcedure需要花费大量的时间,c#,sql-server,performance,entity-framework-6,C#,Sql Server,Performance,Entity Framework 6,我正在ASP.NET MVC5中运行EF6(v6.2.0) 当通过EF6的SqlQuery()函数执行某个StoredProcess时,我必须等待大约2分钟(!)才能在内存中获得结果 由于一些复杂的计算,StoredProcedure在数据库中大约需要9-12秒,并使用11个参数调用: exec sp_Calculation @q, @y, @gn, @gesa, @rg, @cl, @yc, @vlv, @vlb, @ugv, @ugb 结果是大约2.1MB的数据(~9000行,49列) 总
exec sp_Calculation @q, @y, @gn, @gesa, @rg, @cl, @yc, @vlv, @vlb, @ugv, @ugb
结果是大约2.1MB的数据(~9000行,49列)
总执行时间:00:00:11.711
在代码中,我这样称呼它:
dbContext.Database.Log = s => Trace.Write(s);
return await dbContext.Database.SqlQuery<CalculationResult>("exec sp_Calculation @q, @y, @gn, @gesa, @rg, @cl, @yc, @vlv, @vlb, @ugv, @ugb", parameters).ToListAsync(token);
我的第一个猜测是网络是一个瓶颈,但是通过SSMS在Web服务器上调用StoredProc也非常快。所以网络不应该是问题所在
下面是dotTrace的调用堆栈,其中有一个大瓶颈:
奇怪的是本机程序集的执行时间非常长
有人能澄清到底发生了什么以及如何解决这个问题吗
编辑:
我刚刚发现了一个类似的问题,并将尝试了解更多有关它的信息。也许它是网络
编辑2:
我确实需要内存中的所有数据,因为在创建csv文件之前需要进行一些预处理。瓶颈似乎在
snNativeMethodWrapper
中。我不需要帮助来执行与其他库的任务。我只是想在内存中更快地获取数据。我也遇到了同样的问题,当然SSMS的执行速度会更快
问题是,所有记录都被分配给相应的POCO及其属性,它遍历每个值,直到生成一个庞大的对象集
我如何解决这个问题:
我在存储过程中创建了分页(sql级别分页)。
除非你是一个电子人,否则没有人可以一次查看9000多条记录。
因此,在执行存储过程时,只需从结果集中获取10-100条记录
更新:
如果需要检索创建excel的结果集,我建议可能的方法:
- 直接从创建excel文件,获取结果集 从db到C#非常耗时李>
- 如果您在服务器端仍然需要它 那么我建议您使用或任何其他保养良好的产品 在服务器端为您生成excel的第三方库(我使用的是EPPlus) 除SP执行外,我所用的时间不超过5秒 时间)
- 由于EF和ado之间的差异,切换回ado.net生成报告是可行的
- 优化您的查询,优化它
- 如果您的手仍被客户捆住,请忍受当前的加载时间;)李>
- 我也遇到了同样的问题,当然SSM的执行速度会更快
问题是,所有记录都被分配给相应的POCO及其属性,它遍历每个值,直到生成一个庞大的对象集
我如何解决这个问题:
我在存储过程中创建了分页(sql级别分页)。
除非你是一个电子人,否则没有人可以一次查看9000多条记录。
因此,在执行存储过程时,只需从结果集中获取10-100条记录
更新:
如果需要检索创建excel的结果集,我建议可能的方法:
- 直接从创建excel文件,获取结果集 从db到C#非常耗时李>
- 如果您在服务器端仍然需要它 那么我建议您使用或任何其他保养良好的产品 在服务器端为您生成excel的第三方库(我使用的是EPPlus) 除SP执行外,我所用的时间不超过5秒 时间)
- 由于EF和ado之间的差异,切换回ado.net生成报告是可行的
- 优化您的查询,优化它
- 如果您的手仍被客户捆住,请忍受当前的加载时间;)李>
当链接服务器之间的负载较低时,一切都会按预期的速度运行。问题是数据库和链接服务器之间的负载较重。 本机API很难通过SQL网络接口推送整个记录集。所以代码本身没有问题
当链接服务器之间的负载较低时,一切都会按预期的速度运行。ORM不用于报告查询。等待9K行返回,将它们转换为列表,然后使用它们也很慢,可能会导致大量的重新分配。使用IEnumerable开始处理结果。毕竟,对于报告或导出,您不需要所有数据,您可以在第一行到达后立即开始写入结果。您还可以使用像Dapper这样的microORM。因为您不需要处理实体,所以不需要更改跟踪、更新支持和完整ORM提供的所有其他功能。只要将DbDataReader行映射到CalculationResult对象,我们就可以在整个应用程序中使用EF6,并使用它的几乎所有功能。所以现在换掉不是一个选择。问题是,加载数据后会有更多的处理。但光是装载就要花那么长时间。在显示跟踪时间时,EF6是否考虑了对象分配?这不是使用错误功能的理由。所以也使用EF。衣冠楚楚。我认为ADO.NET也是必要的。ORM仍然不适合报告导出查询。简单的ADO.NET给了我相同的结果,因此EF6本身没有问题。有些本地的东西看起来很疯狂,但我需要知道到底哪里出了问题。ORMs不适合报告查询。等待9K行返回,将它们转换为列表exec sp_Calculation @q, @y, @gn, @gesa, @rg, @cl, @yc, @vlv, @vlb, @ugv, @ugb -- @q: 'null' (Type = Int32, IsNullable = false) -- @y: '1101' (Type = Int16, IsNullable = false) -- @gn: 'null' (Type = Int32, IsNullable = false) -- @gesa: '1' (Type = Byte, IsNullable = false) -- @rg: 'null' (Type = Int32, IsNullable = false) -- @cl: '4' (Type = Byte, IsNullable = false) -- @yc: '17' (Type = Int16, IsNullable = false) -- @vlv: 'null' (Type = Int16, IsNullable = false) -- @vlb: 'null' (Type = Int16, IsNullable = false) -- @ugv: 'null' (Type = Int16, IsNullable = false) -- @ugb: 'null' (Type = Int16, IsNullable = false) -- Executing asynchronously at 19.07.2018 18:27:23 +02:00 -- Completed in 114479 ms with result: SqlDataReader