Linq2Sql的Perf问题

时间:2011-08-08 23:48:27

标签: c# sql performance linq-to-sql

我正在尝试在使用Linq2Sql的应用程序中提高性能。我发现了一种非常慢的特定方法。这是一个讨厌的,嵌套的.Sum()语句。执行时,返回数据只需30多秒。总数据行可能是3000.如果我使用LinqPad生成并运行它的sql,我会在不到一秒的时间内恢复数据。

我不知道框架会在这里返回什么。 应该被where子句过滤掉,对吗?我也想象它会从内到外发挥作用。从where开始,然后对所有得分求和,然后在T2中求和,然后在T1中求和。

ParentTable.Table1.Sum
(
 t1=>
  t1.Table2.Sum
  (
   t2=>
     t2.Table3.Where(t3=>t3.Table4.Id==275).Sum(t3=>t3.Score)
  )
)

为了使事情进一步复杂化,LinqPad可以在不到半秒的时间内执行相同的语句。

我想我的问题是,为什么Linq2Sql和TSql的速度有这么大差异? Linq是否会在应用程序框中恢复所有行并进行过滤?

现在,webapp在用户会话的生命周期中重用相同的DataContext。我总是觉得你应该在每次手术后处理掉它。这可能是问题吗?

让我补充一点,当我描述SQL(从应用程序执行时)时,我没有什么可担心的。读取数为< 15,CPU为< 5,写入没什么,持续时间最多为20.所以我很确定它不是语句的执行,而是LINQ2Sql的一些处理。

1 个答案:

答案 0 :(得分:0)

我想我知道发生了什么。

数据关系并不像LINQ那样简单。 表1引用了表2 表2确实参考了表3 然而 Table4并没有直接绑定到T3,还有其他2个。

这不应该影响任何东西,但在Table1对象的部分类中填充是一个自定义的全局“缓存”字典。每当您从Table1请求ANYTHING时,它都会确保该表中的每条记录都被加载到内存中。所有对象都存在相同的模式。

所以基本上,通过快速简单的总和,它将所有6个表(t1,t2,t3,t3b,t3c,t4)中的每条记录加载到内存中,然后进行总和。

在后续请求中,它将查看缓存中的每个项目以查看它是否过时。这也解释了数据不一致的另一个问题。

哇......哇哇!