我正在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的调用栈,它具有很大的瓶颈: 奇怪的是,本机程序集的执行时间非常长。
有人可以弄清楚那里到底发生了什么以及如何解决该问题吗?
编辑: 我刚刚发现了一个question,也遇到了类似的问题,并将尝试找到更多有关此问题的信息。也许是是网络。
编辑2:
由于需要一些预处理,因此我确实需要内存中的所有数据,然后才能从中创建一个csv文件。瓶颈似乎在SNINativeMethodWrapper
中。我不需要其他库来执行任务的帮助。我只是想更快地获取内存中的数据。
答案 0 :(得分:2)
我遇到了同样的问题,并且离线SSMS的执行速度会更快。
问题在于,所有记录都分配给各自的POCO,并且其属性会遍历每个值,直到产生大量对象为止。
我为解决该问题所做的事情:
我在sproc(SQL级分页)中创建了一个分页。 除非您是CYBORG,否则任何人一次都无法查看9000多个记录。 因此,执行存储过程时,只需从结果集中获取10-100条记录即可。
已更新:
如果您需要检索用于创建Excel的结果集,我建议您这样做的可能方法:
答案 1 :(得分:1)
问题是数据库和链接服务器之间的负担很重。 本机API很难通过SQL网络接口推送整个记录集。因此,代码本身没有问题。
当链接服务器之间的负载很低时,一切都可以按预期的速度运行。