优化foreach循环

时间:2011-07-19 14:44:07

标签: c# linq nhibernate

我有一些代码将记录从数据库中拉出来然后我进行简单的比较以检查记录是否与特定模块和响应匹配,然后使用计数并显示统计信息。不幸的是,当数据库中的任何记录超过1000条时,它会非常慢。

在nHibernate中,我启用了Lazy加载,这在初始查询时间有所帮助,但当它到达这个部分时,它必须深入研究它会减慢很多。我想问题是它从很多不同的表中提取数据来获取这些统计数据。

从某些研究看来,我应该能够通过编写linq语句而不是使用foreach循环来加快速度,但是我已经进行了几次尝试而且我没有走得太远。我想知道是否有人可以帮我指出正确的方向。或者对一本好的Linq教程或书籍,因为我对这个主题知之甚少

另外我看到在类似的情况下,人们建议将一个作业放入sql server来填充另一个用于查找的表,但是如果可能的话我想避免这种情况。

这是代码。

int modules = 0;
var sessionsWithPullHits = from session in m_sessions where session.PullHits.Count > 0 select session;

foreach (ISession<PullHitRecord, PushHitRecord> session in sessionsWithPullHits)
{
    foreach (var pullHit in session.PullHits)

    if ((pullHit.Module == _Module) && (pullHit.Response == _response))
    {
        modules++;
    }
}

非常感谢有人给予的任何帮助。

4 个答案:

答案 0 :(得分:4)

LINQ:

var modules = (from session in m_sessions
               from pullHit in session.PullHits
               where pullHit.Module == _Module && pullHit.Response == _response
               select pullHit).Count();

注意,我不确定这将如何转换为SQL,但它是一个LINQ语句,所以应该工作。

答案 1 :(得分:2)

@George Duckett的答案是用LINQ替换foreach代码。或者,您可以使用流畅的语法表达相同的查询,如下所示:

var modules = m_sessions
.SelectMany(session => session.PullHits, 
            (session, pullHits) => new { pullHits = pullHits })
.Where(session => session.pullHits.Module == _Module && 
                  session.pullHits.Response == _response)
.Count();

这不是那么漂亮,但是得到的IL更小,可能会给你带来更好的结果。此外,这个版本仍然提供稍微小一点的代码,并可能带来小的收益。测试并看:

var modules = m_sessions
  .Select(session => session.PullHits
      .Count(pullHit => pullHit.Module == _Module && 
                        pullHit.Response == _response))
  .Sum();

免责声明:我不支持过早优化,我只启用它:-)

答案 2 :(得分:1)

如果您要做的只是获取会话数,那么最好将_Module和_response传递给SP,然后让DB进行计数,只返回计数。

当然,如果你做得更多,这是不适用的。但是返回许多你不能使用的决定并没有效率。

答案 3 :(得分:0)

我会考虑管理你桌子上的指数。向连接中使用的列添加索引会对性能产生显着影响。请参阅此reference

以下是其他SQL性能调优技巧的列表:Performance Tuning SQL Server Joins

相关问题