在EF6中执行StoredProcedure需要花费大量时间

时间:2018-07-20 07:40:44

标签: c# sql-server performance entity-framework-6

我正在ASP.NET MVC5中运行EF6(v6.2.0)。

通过EF6的SqlQuery()函数执行某个StoredProcedure时,我必须等待大约2分钟(!)才能在内存中获取结果。

由于某些复杂的计算,StoredProcedure在数据库中大约需要9到12秒的时间,并使用11个参数进行调用:

exec sp_Calculation @q, @y, @gn, @gesa, @rg, @cl, @yc, @vlv, @vlb, @ugv, @ugb

结果约为 2.1 MB 数据(〜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);

踪迹:

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

我的第一个猜测是网络是瓶颈,但是通过SSMS在Web服务器上调用StoredProc也非常快。因此网络应该不是问题。

这是dotTrace的调用栈,它具有很大的瓶颈: enter image description here 奇怪的是,本机程序集的执行时间非常长。

有人可以弄清楚那里到底发生了什么以及如何解决该问题吗?

编辑: 我刚刚发现了一个question,也遇到了类似的问题,并将尝试找到更多有关此问题的信息。也许是是网络

编辑2: 由于需要一些预处理,因此我确实需要内存中的所有数据,然后才能从中创建一个csv文件。瓶颈似乎在SNINativeMethodWrapper中。我不需要其他库来执行任务的帮助。我只是想更快地获取内存中的数据。

2 个答案:

答案 0 :(得分:2)

我遇到了同样的问题,并且离线SSMS的执行速度会更快。

问题在于,所有记录都分配给各自的POCO,并且其属性会遍历每个值,直到产生大量对象为止。

我为解决该问题所做的事情:

我在sproc(SQL级分页)中创建了一个分页。 除非您是CYBORG,否则任何人一次都无法查看9000多个记录。 因此,执行存储过程时,只需从结果集中获取10-100条记录即可。

已更新:

如果您需要检索用于创建Excel的结果集,我建议您这样做的可能方法:

  • 直接从sql创建excel文件,并获取结果集 从db到C#非常耗时。
  • 如果在服务器端仍需要它 那么我建议您使用EPPlus或任何其他维护良好的 第三方库在服务器端为您生成excel(我使用的是EPPlus 对我来说,不超过5秒(不包括SP执行) 时间)
  • 由于EF和ADO之间的performance不同,切换回ado.net生成报告是可行的
  • 优化查询,优化查询。
  • 如果客户仍然束手无策,请忍受当前正在经历的加载时间;)

答案 1 :(得分:1)

问题是数据库和链接服务器之间的负担很重。 本机API很难通过SQL网络接口推送整个记录集。因此,代码本身没有问题。

当链接服务器之间的负载很低时,一切都可以按预期的速度运行。