Linq2Sql的性能问题

3
我正在试图提高一个大量使用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
你怎么知道是这个“Sum”需要30秒才能执行? - Dan Abramov
1
在整个方法周围添加了一个秒表,另一个秒表则仅在求和周围。求和至少需要30秒,而整个方法只需30纳秒。 - user60456
你尝试过编译查询吗? - Iraklis
我猜 ti 应该是指 t1,但 Table4 是什么,它与 where 子句如何关联到 Table3? - NetMage
生成的 SQL 是什么? - saus
显示剩余7条评论
1个回答

0

我想我已经弄清楚了发生了什么。

数据关系并不像LINQ所描述的那样简单。 Table1引用了Table2 Table2引用了Table3 然而 Table4并没有直接与T3相关联,还有两个其他表在中间。

这不应该影响任何事情,但是在Table1对象的部分类中插入了一个自定义全局“缓存”字典。每次您从Table1请求任何内容时,它都会确保将该表的每个记录加载到内存中。所有对象都存在相同的模式。

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

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

哇...真是太棒了!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接